Jvm 堆内存内部结构
所有通过new创建的对象的内存都在堆中分配,其大小可以通过-Xmx和-Xms来控制。堆被划分为新生代和老年代,新生代又被进一步划分为Eden(伊甸园)和Survivor(幸存者)区,老年代,在后面不是堆区是永恒代(方法区),为了进一步了解堆内存里的结构,我们先看看后面要讲的一种垃圾回收算法,分代算法,回收垃圾的过程,通过这个过程的分析,进一步了解堆区里的结构细节,结构图如下所示:
最后的永恒代,放常用库文件和方法。
Eden和survivor的比例为8:1,年轻代中的对象基本都是朝生夕死的(80%以上),老年代比年轻代内存大。如果老年代内存满了,就会触发major GC或者full GC。触发full GC就会出现所谓的STW(stop the world)现象。即所有的进程都挂起等待清理垃圾。
major GC是回收老年代的垃圾。Full GC是回收老年代和年轻代的垃圾。
JVM的垃圾回收器判定是否是垃圾数据的一般方法:
许多Java的垃圾收集器都使用了引用的根集GC Roots,作为分析对象存活与否的依据。引用的根集是正在执行的Java程序随时都可以访问引用的变量的集合——也就是存在堆栈或是静态存储空间上的引用变量。从这些根集变量出发可直接或是间接到达的对象,垃圾收集器会认为这些对象是生命尚存的对象;相对的从这些根集变量出发通过任意途径都无法到达的对象,就是死亡的,它们就会成为下一次垃圾收集的对象。
---------------------------------------------------------------------------------------------------------------
1、所有通过new创建的对象的内存都存放到堆中。
2、堆内存分新生代,老年代。永恒代是方法区,不属于堆。
新生代:eden(伊甸园),Survivor(幸存者)(S0,S1)。s0和s1是两个大小对称的区域。
3、新new的对象,放到新生代的eden中。
4、 当eden满了的时候,触发minor gc(普通的回收器),判断并回收垃圾对象。没有被清理的对象,放到S0或者S1中,只能放其中的一个,比如放到了S0中,然后给这些幸存的对象计数,然后把右边的S1里面的幸存对象复制到S0,幸存次数+1.然后右边S1里面的内容全部删除掉。当幸存对象的年纪到了一定年纪,就到了老年代。当新生代不断的增加,直到老年代也被占满了,触发全局垃圾回收器。major GC 或者full GC.触发full GC就会出现所谓的STW(stop the world)现象。既所有的进程都是挂起等待清理垃圾。执行FGC时,整个程序就是卡顿状态。major GC 专门回收老年代垃圾,Full GC 是回收老年代+新生代垃圾的。
5、新生代中,eden和survivor占比是8:1。也就是新生代内存中,eden占用80%。suivior各占比10%。同时也说明,新生代永远有10%的空余。因为新生代里面的对象一般都是招生夕死,大概占了80%。
------------------------------------------------------------------