意义:设置堆内存的最大值
意义:设置新生代的初始值和最大值
意义:设置新生代的初始值
意义:设置新生代的最大值
意义:设置年老代和年轻代的比例。比如:-XX:NewRatio=8表示老年代的内存:年轻代的内存=8:1。老年代占堆内存的8/9;年轻代占堆内存的1/9。
意义:设置新生代中Eden区和一个Survivor区的大小比例。如:-XX:SurvivorRatio=8表示存活区Eden区占据年轻代的8/10,一个Survivor区占据年轻代的1/10.
意义:更改方法区的大小
2.1.1 java.lang.OutOfMemoryError: Java heap space ------>java堆内存溢出 此种情况最常见,一般由于内存泄露或者堆的大小设置不当引起。对于内存泄露,需要通过内存监控软件查找程序中的泄露代码,而堆大小可以通过虚拟机参数-Xms,-Xmx等修改。 2.1.2 java.lang.OutOfMemoryError: PermGen space ------>java永久代溢出 即方法区溢出了,一般出现于大量Class或者jsp页面,或者采用cglib等反射机制的情况,因为上述情况会产生大量的Class信息存储于方法区。此种情况可以通过更改方法区的大小来解决,使用类似-XX:PermSize=64m -XX:MaxPermSize=256m的形式修改。另外,过多的常量尤其是字符串也会导致方法区溢出。
虚拟机遇到一条new指令的时候,首先检查这个指令的参数能否在常量池中找到这个类的引用。并检查这个符号引用代表的类是否已经被加载过,如果没有,那就必须先执行相应的类加载过程。
新生对象需要分配内存,对象所需内存大小在类加载完成后便可以确定。内存分配的方式有两种,一种是“指针碰撞”,一种是“空闲列表”。选择哪种分配方式由Java堆是否规整决定,而Java堆是否规整又由所采用的垃圾收集器是否带有压缩整理功能决定。
指针碰撞
使用适用场合:堆内存规整(没有内存碎片)的情况下。原理:用过的内存全部整合到一边,没有用过的内存放到另一边。中间有一个分界指针,只需要想着没用过的内存方向将该指针移动对象内存大小的位置即可。GC收集器:Serial,ParNew 空闲列表适用场合:堆内存不规整的情况原理:虚拟机维护一个列表,该列表会记录哪些内存块是可用的,在分配的时候,找一个足够大的内存块划分给对象实例,最后更新列表记录。GC收集器:CMS可能有多个线程同时在堆上创建对象,这时候创建对象要考虑线程安全的问题。解决办法如下:
CAS+失败重试获取空间TLAB:为每一个线程预先在Eden区分配一块内存,JVM在给对象分配内存的时候,首先在TLAB上分配,当对象大于TLAB中剩余内存或者TLAB内存已经使用完毕,再使用上述的CAS进行内存的分配。将分配给对象的,除了对象头之外的所有内存空间都初始化为零值。保证对象的实例字段没有初始化也可以使用。
这个init方法的内容有 父类变量初始化 父类语句块 父类构造函数 子类变量初始化 子类语句块 子类构造函数
在堆上有一个句柄池用来存放诸多句柄。每一个句柄有两个指针,一个指针指向堆中的对象,另一个指针指向这个对象的类信息,这个类信息是存放在方法区的。
局部变量表的数据直接通过指针指向堆中的对象,这个对象里面存放着一个指针,这个指针指向这个对象的类信息,同样,类信息存放在方法区当中。
这两种对象访问⽅式各有优势。使⽤句柄来访问的最⼤好处是 reference 中存储的是稳定的句柄地 址,在对象被移动时只会改变句柄中的实例数据指针,⽽ reference 本身不需要修改。使⽤直接指针 访问⽅式最⼤的好处就是速度快,它节省了⼀次指针定位的时间开销
一个对象是否有虚引用的存在,不会对其生存时间造成影响,也无法通过虚引用得到一个对象。为一个对象设置虚引用的唯一目的是能在这个对象被回收时收到一个系统通知
类的生命周期有 加载,验证,准备,解析,初始化,使用,卸载。其中加载,验证,准备,初始化,卸载这个五个阶段是严格按照这个顺序开始的,但是解析则不确定。
JVM相关,崔腾翔的博客,除了G1垃圾收集器之外,都讲得挺仔细的。 https://blog.csdn.net/weixin_42045759/article/details/105580874
G1收集器看这篇文章就够了 https://blog.csdn.net/mlplds/article/details/108695611 https://www.cnblogs.com/wjh123/p/11146195.html G1收集器的运作⼤致分为以下⼏个步骤: 初始标记 并发标记 最终标记 筛选回收 G1收集器在后台维护了⼀个优先列表,每次根据允许的收集时间,优先选择回收价值最⼤的Region(这
Java源代码编译后形成字节码文件,通过jvm的类加载机制加载到内存,然后使用,最后卸载。 类加载机制包括加载,验证,准备,解析,初始化
以 GC Roots 为起始点进行搜索,可达的对象都是存活的,不可达的对象可被回收。 Java 虚拟机使用该算法来判断对象是否可被回收,GC Roots 一般包含以下内容:
虚拟机栈中局部变量表中引用的对象本地方法栈中 JNI 中引用的对象方法区中类静态属性引用的对象方法区中的常量引用的对象