深入了解jvm回收机制

目的

主要介绍java 垃圾回收如何与hotspot JVM配合使用的基础知识。在了解了垃圾收集器的功能后,了解Visual VM监控垃圾收集的过程。

探索JVM架构

Hotspot 架构

HotSpot JVM 的架构支持强大的特性和能力基础,并支持实现高性能和大规模可扩展性的能力。例如,HotSpot JVM JIT 编译器生成动态优化。换句话说,它们在 Java 应用程序运行时做出优化决策,并生成针对底层系统架构的高性能本机机器指令。此外,通过其运行时环境和多线程垃圾收集器的成熟演变和持续工程,HotSpot JVM 即使在最大的可用计算机系统上也能产生高可扩展性。


Hotspot 架构

关键组件

在调整性能时,JVM 有三个组件是重点。堆是存储对象数据的位置。然后,此区域由启动时选择的垃圾回收器管理。大多数优化选项都与调整堆大小和根据您的情况选择最合适的垃圾回收器有关。JIT 编译器对性能也有很大的影响,但很少需要使用较新版本的 JVM 进行调优。


Key Hotspot Components

垃圾回收

什么是自动垃圾回收?

自动垃圾回收是查看堆内存、识别哪些对象正在使用以及哪些对象未使用以及删除未使用对象的过程。正在使用的对象或引用的对象意味着程序的某些部分仍保留指向该对象的指针。未使用的对象或未引用的对象不再被程序的任何部分引用。因此,可以回收未引用对象使用的内存。

在像C这样的编程语言中,分配和释放内存是一个手动过程。在 Java 中,释放内存的过程由垃圾回收器自动处理。基本过程分为以下几步:

1. 标记

标记的作用是垃圾回收器识别哪些内存正在使用和哪些未使用。
引用的对象以蓝色显示;未引用的对象以金黄色显示。
在标记阶段,所有对象将被扫描,并被标记。如果必须扫描系统中的所有对象,这可能是一个非常耗时的过程。


标记

2. 正常删除

正常删除会删除未引用的对象,留下引用的对象和指向可用空间的指针。
内存分配器保存对可用空间块的引用,可以在其中分配新对象。


正常删除

使用压缩进行删除

若要进一步提高性能,除了删除未引用的对象外,还可以压缩其余引用的对象。通过将引用的对象移动到一起,这使得新的内存分配更加容易和快捷。


压缩删除

为什么要进行按“代”进行垃圾回收?

通过前面的描述,我们可以了解到标记和压缩jvm中所有的对象是低效的、耗时的。随着分配的对象越来越多,对象的列表会越来越长,从而导致垃圾回收的时间越来越长。然而通过对应用程序的实际分析发现,大部分对象的使用时间都是短暂的。
下面是此类数据的示例,Y 轴显示分配的字节数,X 访问显示随时间分配的字节数。


image.png

如您缩减,随着时间的推移,保留分配的对象越来越少。所以实际上,大多数的对象寿命非常短,正如图左侧的较高值所示。

JVM年龄代

JVM代分布

堆空间包括:年轻代、年老代、永生代。
年轻代(eden) 是分配和老化所有新生对象的地方。当年轻代被填满时,会导致小的垃圾回收。
S0S1是两个大小相同的内存区域,主要存放每次垃圾回收后eden区存活的对象,作为对象从eden过渡到年老代的缓冲地带。
年老代主要存放生命周期长的存活对象。通常为年轻代设置阈值,当达到该年龄后,对象将被移动到年老代。
永生代 主要存放所有已加载的类信息、方法信息、常量池等。可通过-XX:PermSize和-XX:MaxPermSize来指定持久带初始化值和最大值。Permanent Space并不等同于方法区,只不过是Hotspot JVM用Permanent Space来实现方法区而已,有些虚拟机没有Permanent Space而用其他机制来实现方法区。

对象分配和老化的过程

  1. 任何新对象都会被分配到eden区,S0、S1开始都是空的


    image.png
  2. 当eden区被填满时,将会触发一次小的垃圾回收


    image.png
  3. 此时被引用的对象将会被移动到S0,未被引用的对象将被删除


    image.png
  4. 在下一次的Minor GC中,Eden区的情况和上面一致,没有引用的对象被回收,存活的对象被复制到survivor区。然而在survivor区,S0的所有的数据都被复制到S1,需要注意的是,在上次minor GC过程中移动到S0中的两个对象在复制到S1后其年龄要加1。此时Eden区S0区被清空,所有存活的数据都复制到了S1区,并且S1区存在着年龄不一样的对象


    image.png
  5. 再下一次Minor GC则重复这个过程,这一次survivor的两个区对换,存活的对象被复制到S0,存活的对象年龄加1,Eden区和另一个survivor区被清空。


    image.png
  6. 下面演示一下Promotion过程,再经过几次Minor GC之后,当存活对象的年龄达到一个阈值之后(可通过参数配置,默认是8),就会被从年轻代Promotion到老年代。


    image.png
  7. 随着Minor GC一次又一次的进行,不断会有新的对象被promote到老年代。
    随着MinorGC一次又一次的进行,不断会有新的对象被promote到老年代。

  8. 上面基本上覆盖了整个年轻代所有的回收过程。最终,Major GC将会在老年代发生,老年代的空间将会被清除和压缩。


    image.png

总结

从上面的过程可以看出,Eden区是连续的空间,且Survivor总有一个为空。经过一次GC和复制,一个Survivor中保存着当前还活着的对象,而Eden区和另一个Survivor区的内容都不再需要了,可以直接清空,到下一次GC时,两个Survivor的角色再互换。因此,这种方式分配内存和清理内存的效率都极高,这种垃圾回收的方式就是著名的“停止-复制(Stop-and-copy)”清理法(将Eden区和一个Survivor中仍然存活的对象拷贝到另一个Survivor中),这不代表着停止复制清理法很高效,其实,它也只在这种情况下(基于大部分对象存活周期很短的事实)高效,如果在老年代采用停止复制,则是非常不合适的。老年代存储的对象比年轻代多得多,而且不乏大对象,对老年代进行内存清理时,如果使用停止-复制算法,则相当低效。一般,老年代用的算法是标记-压缩算法,即:标记出仍然存活的对象(存在引用的),将所有存活的对象向一端移动,以保证内存的连续。在发生Minor GC时,虚拟机会检查每次晋升进入老年代的大小是否大于老年代的剩余空间大小,如果大于,则直接触发一次Full GC,否则,就查看是否设置了-XX:+HandlePromotionFailure(允许担保失败),如果允许,则只会进行MinorGC,此时可以容忍内存分配失败;如果不允许,则仍然进行Full GC(这代表着如果设置-XX:+Handle PromotionFailure,则触发MinorGC就会同时触发Full GC,哪怕老年代还有很多内存,所以,最好不要这样做)。
关于方法区(共享内存区的持久代)即永久代的回收,永久代的回收有两种:常量池中的常量,无用的类信息,常量的回收很简单,没有引用了就可以被回收。对于无用的类进行回收,必须保证3点:

  • 类的所有实例都已经被回收
  • 加载类的ClassLoader已经被回收
  • 类对象的Class对象没有被引用(即没有通过反射引用该类的地方)

永久代的回收并不是必须的,可以通过参数来设置是否对类进行回收。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容