java虚拟机_堆:
要点:
参考:
https://blog.csdn.net/qq_37141773/article/details/103138476#%E4%BA%8C%E3%80%81%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%BB%84%E6%88%90
https://blog.csdn.net/lhl1124281072/article/details/80524837
老年代,年轻代
对于这个基本组成大家应该都有所了解,对就是由年轻代和老年代组成,年轻代又分为伊甸园区和survivor区,survivor区中又有from区和to区.
其实new出来的对象一般都放在Eden区,那么为什么叫伊甸园区呢,伊甸园就是亚当夏娃住的地方,不就是造人的地方么?所以我们new出来的对象就是放在这里的,那当Eden区满了之后呢?
假设我们给对分配600M内存,这个是可以通过参数调节的,我们后文再讲。那么老年代默认是占2/3的,也就是差不多400M,那年轻代就是200M,Eden区160M,Survivor区40M。
3.3 如何确定垃圾
3.3.1 引用计数器法
给对象添加一个引用计数器,每当由一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不可能再被使用的。 不过会有循环引用的问题,两个垃圾惺惺相惜。。。
3.3.2 可达性分析算法
顺藤摸瓜,能摸到的瓜都是好瓜。通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时(用图论的话来说就是从GC Roots到这个对象不可达),则证明此对象是不可用的。
垃圾回收过程
经历了第一次minor gc后,没有被清理的对象就会被移到From区,如上图。
那么如果第二次新的对象又把Eden区放满了,那么又会执行minor gc,但是这次会连着From区一起gc,然后将Eden区和From区存活的对象都移到To区域,对象头中分代年龄都+1,如上图
那么当第三次Eden区又满的时候,minor gc就是回收Eden区和To区域了,TEden区和To区域还活着的对象就会都移到From区,如上图。说白了就是Survivor区中总有一块区域是空着的,存活的对象存放是在From区和To区轮流存放,也就是互相复制拷贝,这也就是垃圾回收算法中的复制-回收算法
如果一个对象经历了一个限值15次gc的时候,就会移至老年代。那如果还没有到限值,From区或者To区域也放不下了
Full GC
那当我们老年代满了会发生什么呢?当然是我们上面说过的Full GC,但是你仔细看我们写的这个程序,我们所有new出来的HeapTest对象都是存放在heapLists中的,那就会被这个局部变量所引用,那么Full GC就不会有什么垃圾对象可以回收,可是内存又满了,那怎么办?
OOM
那么Full GC就不会有什么垃圾对象可以回收,可是内存又满了,就是我们就算没见过也总听过的OOM