堆内存垃圾回收过程
第一步
新生成
的对象首先放到Eden
区,当Eden区满了
会触发Minor GC
。
第二步
第一步GC活下来的对象,会被移动到survivor
区中的S0区,S0区满了之后会触发Minor GC
,S0区存活下来的对象会被移动到S1区,S0区空闲。
S1满了之后在GC,存活下来的再次移动到S0区,S1区空闲,这样反反复复GC,每GC一次,对象的年龄就涨一岁
,达到某个值后(15),就会进入老年代
。
第三步
在发生一次Minor GC
后(前提条件),老年代可能会出现Major GC
,这个视垃圾回收器而定。
Full GC触发条件
-
手动调用System.gc,会不断的执行Full GC
-
老年代空间不足/满了
-
方法区空间不足/满了
注意
们需要记住一个单词:stop-the-world
。它会在任何一种GC算法中发生。stop-the-world 意味着JVM因为需要执行GC而停止
应用程序的执行。
当stop-the-world 发生时,除GC所需的线程外,所有的线程
都进入等待
状态,直到GC任务完成。GC优化很多时候就是减少stop-the-world 的发生。
回收哪些区域的对象
需要注意的是,JVM GC只回收堆内存
和方法区内
的对象。而栈内存
的数据,在超出作用域后会被JVM自动释放掉,所以其不在JVM GC的管理范围内。
堆内存常见参数配置
参数 | 描述 |
---|---|
-Xms | 堆内存初始大小,单位m、g |
-Xmx | 堆内存最大允许大小,一般不要大于物理内存的80% |
-XX:PermSize | 非堆内存初始大小,一般应用设置初始化200m,最大1024m就够了 |
-XX:MaxPermSize | 非堆内存最大允许大小 |
-XX:NewSize(-Xns) | 年轻代内存初始大小 |
-XX:MaxNewSize(-Xmn) | 年轻代内存最大允许大小 |
-XX:SurvivorRatio=8 | 年轻代中Eden区与Survivor区的容量比例值,默认为8,即8:1 |
-Xss | 堆栈内存大小 |
-XX:NewRatio=老年代/新生代 | 设置老年代和新生代的大小比例 |
-XX:+PrintGC | jvm启动后,只要遇到GC就会打印日志 |
-XX:+PrintGCDetails | 查看GC详细信息,包括各个区的情况 |
-XX:MaxDirectMemorySize | 在NIO中可以直接访问「直接内存」,这个就是设置它的大小,不设置默认就是最大堆空间的值-Xmx |
-XX:+DisableExplicitGC | 关闭System.gc() |
-XX:MaxTenuringThreshold | 垃圾可以进入老年代的年龄 |
-Xnoclassgc | 禁用垃圾回收 |
-XX:TLABWasteTargetPercent | TLAB占eden区的百分比,默认是1% |
-XX:+CollectGen0First | FullGC时是否先YGC,默认false |