美文网首页
JVM 垃圾回收机制之堆的分代回收

JVM 垃圾回收机制之堆的分代回收

作者: 千锋陈老师 | 来源:发表于2019-05-05 16:51 被阅读0次

    JVM垃圾回收机制之堆的分代回收

    前言

    前文我们了解了Java的GC机制,对于堆中的对象,JVM采用引用计数和可达性分析两种算法来标记对象是否可以清除,本文中我们还会了解到JVM将对分成了不同的区域,以便于更好的回收对象。

    堆的分代

    Java的堆是JVM中最大的一块内存区域,主要保存Java中各种类的实例。为了更好的管理堆中各个对象的内存,包括分配内存和回收内存。

    JVM将堆分成了几块区域:

    新生代(Young)

    新生代又分为:

    Eden

    From Survivor

    To Survivor

    老年代(Old)

    其中新生代占堆的1/3空间,老年代占堆的2/3空间。

    而新生代中的Eden占新生代的8/10,From Survivor和To Survivor各占新生代的1/10。

    堆模型如图:

    从上图中我们可以看出:堆是由新生代和老年代组成,默认情况下,新生代 ( Young ) 与老年代 ( Old ) 的比例为 1:2 。其中,新生代 ( Young ) 又分为 Eden 和 From Survivor 、To Survivor区域。默认情况下,Eden 和from、to的比例为 :8 : 1 : 1 。JVM 每次只会使用 Eden 和其中的一块 Survivor 区域来为对象服务,所以无论什么时候,总是有一块 Survivor 区域是空闲着的。因此,新生代实际可用的内存空间为 9/10 ( 即90% )的新生代空间。

    堆的GC机制

    堆中的GC分为两种:

    Minor GC

    Full GC

    Minor GC发生在新生代,采用的算法是复制算法。

    Java中新创建的对象都在新生代中,当对象被判定为死亡时(也就是无法访问),就会被GC回收内存,发生Minor GC时,会将Eden和From Survivor区域中的存活的对象复制到To Survivor区域中,然后将Eden和From survivor区域进行清理。

    当一个对象活过了一次Minor GC后,它的年龄就加1,当对象的年龄达到了15时,对象就会被放入老年代。

    Full GC发生在老年代,采用的是标记-清除算法。

    标记:标记的过程其实就是,遍历所有的GC Roots,然后将所有GC Roots可达的对象标记为存活的对象。

    清除:清除的过程将遍历堆中所有的对象,将没有标记的对象全部清除掉。

    当程序运行期间,若可以使用的内存被耗尽的时候,GC线程就会被触发并将程序暂停,随后将依旧存活的对象标记一遍,最终再将堆中所有没被标记的对象全部清除掉,接下来便让程序恢复运行。

    标记-清除算法存在比较大的缺点:

    进行GC时需要暂停应用程序,所以导致用户体验变差

    会产生许多不连续的内存空间

    所以我们一般会避免出现Full GC。

    JVM参数

    堆的初始大小、新生代、老年代的大小都可以通过JVM的参数进行配置。

    下面是一些常用的JVM参数:

    -Xms初始堆大小。如:-Xms256m

    -Xmx最大堆大小。如:-Xmx512m

    -Xmn新生代大小。通常为 Xmx 的 1/3 或 1/4。新生代 = Eden + 2 个 Survivor 空间。实际可用空间为 = Eden + 1 个 Survivor,即 90%

    -Xss线程的堆栈大小

    -XX:NewRatio新生代与老年代的比例,如 –XX:NewRatio=2,则新生代占整个堆空间的1/3,老年代占2/3

    -XX:SurvivorRatio新生代中 Eden 与 Survivor 的比值。默认值为 8。即 Eden 占新生代空间的 8/10,另外两个 Survivor 各占 1/10

    -XX:PermSize永久代(方法区)的初始大小

    -XX:MaxPermSize永久代(方法区)的最大值

    -XX:+PrintGCDetails打印 GC 信息

    下面是Eclipse的JVM参数配置方法:

    Window --- Preferences --- Java --- Installed JREs --- 点击Edit

    在Default VM arguments中添加参数:

    总结

    本文我们学习了JVM堆GC的分代机制,堆分为新生代和老年代,新生代中采用Minor GC,使用的是复制算法,老年代中采用Full GC,使用的是标记-清除算法。

    相关文章

      网友评论

          本文标题:JVM 垃圾回收机制之堆的分代回收

          本文链接:https://www.haomeiwen.com/subject/oauhoqtx.html