JVM的自动垃圾回收处理的是不再使用的对象/数组, 这些对象/数组都是存储在堆内存中, 堆内存相关介绍请看这里:
https://blog.csdn.net/j550341130/article/details/82152054
在 Java 中, 堆被划分成两个不同的区域:新生代 ( Young )、老年代 ( Old ).
新生代 ( Young ) 又被划分为三个区域:Eden、From Survivor、To Survivor.
默认比例:
1. 新生代 ( Young ) 与老年代 ( Old ) 的比例的值为 1:2 ( 该值可以通过参数 –XX:NewRatio 来指定 );
2. 新生代 Edem : from : to = 8 : 1 : 1 ( 可以通过参数 –XX:SurvivorRatio 来设定 )
新生代
是基本上所有对象创建/保存的区域, 一般新建的对象会分配到Eden区 ( 另一部分是大对象, 它们会直接放入老年代, 这是为了保留新生代的内存复制效率, 大对象标准可以使用-XX:PretenureSizeThreshold 来设置 ).
JVM 每次只会使用 Eden 和其中的一块 Survivor 区域来为对象服务, 所以无论什么时候, 总是有一块 Survivor 区域是空闲着的. 因此, 新生代实际可用的内存空间为 9/10 ( 即90% )的新生代空间.
每次GC时, 把Eden存活的对象和From Survivor中存活且没超过年龄阈值的对象复制到To Survivor中, To Survivor变为From Survivor, 原From Survivor清空变成To Survivor.
对象在Survivor每熬过一轮Minor GC 年龄就增加1, 当年龄达到一定程度时就会被移动到老年代 ( 年龄阈值默认为15, 可以通过-XX:MaxTenuringThreshold来设置).
所以, 老年代
里的对象大部分都是不容易被回收的对象 ( 另一部分是直接放入老年代的大对象 ), 发生在老年代的MajorGC频率也小于新生代的MinorGC.
MinorGC(次要的) 是发生在新生代的GC, 采用了复制算法.
MajorGC(重要的) 是发生在老年代的GC, 一般也伴随着MinorGC, 它采用了标记-清除算法, 速度比Minor GC慢10倍以上.
当新生代Eden区没有足够的空间进行分配时, 虚拟机将发起一次Minor GC.
老年代空间不足时Full GC, 如果还是不足, 则抛出OOM异常.
GC怎么判断哪些对象是无效的, 其内存是需要回收的呢?
如果某对象不是引用可达的, 说用其需要被回收. 这里有两种可达分析方法:
判断出某些对象没有被引用时就需要回收了, JVM的GC使用了这两种回收算法:
参考:
https://blog.csdn.net/gyqjn/article/details/49848473
https://blog.csdn.net/wnl_csdn/article/details/73865511