GC堆简单了解

Posted jasonboren

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GC堆简单了解相关的知识,希望对你有一定的参考价值。

java堆:所有通过new关键字创建的对象的内存都在堆中分配,其大小可以通过-Xmx和-Xms来控制。堆被划分为新生代和旧生代,新生代又被进一步划分为Eden和Survivor区,最后Survivor由From Space和To Space组成,结构图如下所示:技术图片
新生代:新建的对象都是用新生代分配内存,Eden空间不足的时候,会把存活的对象转移到Survivor中,新生代大小可以由-Xmn来控制,也可以用-XX:SurvivorRatio来控制Eden和Survivor的比例。
旧生代:用于存放新生代中经过多次垃圾回收仍然存活的对象。
Java中的堆也是GC收集垃圾的主要区域。GC分为两种:Minor GC、FullGC(或称为Major GC)。
Minor GC是发生在新生代中的垃圾收集动作,所采用的是复制算法。
新生代几乎是所有Java对象出生的地方,即Java对象申请的内存以及存放都是在这个地方。Java中的大部分对象通常不需长久存活,具有朝生夕灭的性质。当一个对象被判定为 "死亡" 的时候,GC就有责任来回收掉这部分对象的内存空间。新生代是GC收集垃圾的频繁区域。当对象在Eden(包括一个Survivor区域,这里假设是from区域)出生后,在经过一次Minor GC后,如果对象还存活,并且能够被另外一块Survivor区域所容纳(上面已经假设为from 区域,这里应为to区域,即to区域有足够的内存空间来存储Eden和from区域中存活的对象),则使用复制算法将这些仍然还存活的对象复制到另外一块Survivor区域(即to区域)中,然后清理所使用过的Eden以及Survivor区域( 即from区域),并且将这些对象的年龄设置为1,以后对象在Survivor区每熬过一次Minor GC,就将对象的年龄 + 1,当对象的年龄达到某个值时 ( 默认是15岁,可以通过参数 -XX:MaxTenuringThreshold来设定 ),这些对象就会成为老年代。但这也不是一定的,对于一些较大的对象(即需要分配一块较大的连续内存空间)则是直接进入到老年代。

Full GC是发生在老年代的垃圾收集动作,所采用的是标记-清除算法。
现实的生活中,老年代的人通常会比新生代的人"早死"。堆内存中的老年代(Old)不同于这个,老年代里面的对象几乎个个都是在Survivor区域中熬过来的,它们是不会那么容易就 "死掉" 了的。因此,Full GC发生的次数不会有Minor GC那么频繁,并且做一次Full GC要比进行一次Minor GC的时间更长。 另外,标记-清除算法收集垃圾的时候会产生许多的内存碎片(即不连续的内存空间),此后需要为较大的对象分配内存空间时,若无法找到足够的连续的内存空间,就会提前触发一次GC的收集动作。

新生代约占堆大小的 1/3,老年代约占堆大小的 2/3。

永久代回收:(即方法区回收)
JVM的方法区,也被称为永久代。在这里都是放着一些被虚拟机加载的类信息,静态变量,常量等数据。这个区中的东西比老年代和新生代更不容易回收。

参考博文:https://www.cnblogs.com/honey01/p/9475726.html

以上是关于GC堆简单了解的主要内容,如果未能解决你的问题,请参考以下文章

一篇文章让你了解GC垃圾回收器

C#基础:GC机制中如何判断一个对象是否扔在被使用

JAVA GC 简单总结

初步了解JVM第三篇(堆和GC回收算法)

JVM GC总结

面试官问我:谈谈对Java GC的了解?回答完让我回家等消息....