第4讲-深入理解JVM内存分配与回收策略.pptVIP

第4讲-深入理解JVM内存分配与回收策略.ppt

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
第4讲-深入理解JVM内存分配与回收策略

本节内容引入 Java技术体系中所提倡的自动内存管理最终可以归结为自动化地解决了两个问题:给对象分配内存以及回收分配给对象的内存。 对象的内存分配,从大方向上将,就是在堆上分配(但也可能经过JIT编译后被拆散为标量类型并间接地在栈上分配),对象主要分配在新生代的Eden区上,如果启动了本地线程分配缓冲,将按线程优先在TLAB上分配。少数情况也可能直接分配在老年代中,分配的规则并不是百分之百固定的,其细节取决于当前使用的是哪一种垃圾收集器组合,还有虚拟机中与内存相关的参数的设置。 下面讲解集中最普遍的内存分配规则,并通过代码去验证这些规则。本节中的代码在测试时使用Client模式虚拟机运行,没有手工指定收集器组合,换句话说,验证的是使用Serial/Serial Old收集器下(ParNew/Serial Old组合的规则也基本一致)的内存分配和回收策略。 一、对象优先在Eden区分配 大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够空间分配时,虚拟机将发起一次Minor GC。 虚拟机提供了-XX:+PrintGCDetails这个收集器日志参数,告诉虚拟机在发生垃圾收集行为时打印内存回收日志,并且在进程退出的时候输出当前内存各区域的分配情况。在实际应用中,内存回收日志一般都是打印到文件后通过日志工具进行分析。 程序清单1(对象优先在Eden区分配) 程序清单2(对象优先在Eden区分配) jdk1.7下运行结果(对象优先在Eden区分配) 结果分析与总结(对象优先在Eden区分配) 尝试分配3个2MB和1个4MB的对象,在运行时通过-Xms20M、-Xmx20M和-Xmn10M这3个参数限制Java堆大小为20M,且不可扩展,其中10MB分配给新生代,剩下的10M就分配给老年代了-XX:SurvivorRatio=8决定了新生代中Eden和Survivor区的空间比例为8:1,从运行结果可以看到“eden space 8192K、from space 1024K、to space 1024K”的信息,新生代总可用空间为9216KB(Eden区+1个Survivor区的总容量)。 执行testAllocation()中分配allocation4对象的语句时会发生一次Minor GC,这次GC的结果是新生代由6871K变为376K,而总内存占用了几乎没有减少(因为allocation1,2,3三个对象都是存活的,虚拟机几乎没有找到可回收的对象)。这次GC发生的原因是给allocation4分配所需的4MB内存时,发现Eden区已经被占用了6MB,剩余空间不足以分配4MB,因此发生Minor GC。GC期间虚拟机又发现已有的3个2MB对象无法全部放入Survivor空间(Survivor只有1MB),所以只好通过分配担保机制提前转移到老年代。 这次GC结束后,4MB的allocation4对象被顺利分配到Eden中。因此程序执行完的结果是Eden占用4MB(被allocation4占用),Survivor空闲,老年代被占用6MB(allocation1,2,3占用)。 Minor和Full GC有什么不一样? 新生代GC(Minor GC):指发生在新生代的垃圾收集动作,因为Java对象大多都具备朝生夕死的特性,所以Minor GC非常频繁,一般回收速度也比较快。 老年代GC(Major GC/Full GC):指发生在老年代的GC,出现Major GC,经常会伴随至少一次Minor GC(但并非绝对的,在Parallel Scavenge收集器的收集策略里就有直接进行Major GC的策略选择过程)。Major GC的速度一般会比Minor GC慢10倍以上。 二、大对象直接进入老年代 所谓大对象,就是指需要大量连续内存空间的Java对象,最典型的大对象就是那种很长的字符串及数组(byte[]数组就是典型的大对象)。大对象对虚拟机的内存分配来说就是一个坏消息(更加坏的情况就是遇到一群朝生夕死的短命大对象,写程序时应该避免),经常出现大对象容易导致内存还有不少空间时就提前触发垃圾收集以获取足够的连续空间来安置大对象。 虚拟机提供了一个-XX:PretenureSizeThreshold参数,令大于这个设置值的对象直接进入老年代中分配。这样避免在Eden区及两个Survivor区之间发生大量的内存拷贝。 程序清单1(大对象直接进入老年代) 程序清单2(大对象直接进入老年代) 运行结果(jdk1.7,大对象直接进入老年代) 结果分析与总结(大对象直接进入老年代) 我们可以看到Eden空间几乎没有被利用,而老年代10MB空间被使用40%,也就是4MB的allocation对象被直接分配到老年代中,这是因为Pretenur

文档评论(0)

cc880559 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档