JVM 复盘

image.png

JVM 复盘

一 JVM内存块结构
  • 主要是堆栈;方法区;而我们关注比较多的是堆区域,而方法区存放的信息比较少很少会有内存溢出的情况(JDK8 元空间后更加没有)。堆区域分为新生代的Eden/S0/S1区域、老年代分为:Old区域;对象会先到Eden/S0区域,当Eden/S0区域满了;会触发YGC会标记的对象岁数;并压到S1区域。

  • 当S1区域满了、或者对象标记15次;就会把存活的对象放到Old老年代;当老年代满了触发Full GC这时候会把新生代、老年代全部GC一遍。这个时候会触发STW问题,分代的设计主要是最大努力避免对象到Old并触发Full GC 造成STW问题。


    image.png
二、垃圾收集器cms/g1之间的区别
CMS
  • 本质上就是说在CMS GC期间,他需要把用户线程都停下来;对内存对象进行标记清理在我们系统使用CMS一般优化就是内存不够用就调大一些、在极端业务场景的情况下;可能会根据业务场景来设置堆大小,比如调小;触发gc的耗时(RT)降低了;但是GC的频率会提高高;调大了触发GC频率降低了、但每次触发的耗时(RT) 也提高了。

  • 但一般业务场景是可以接受GC造成的停顿耗时;所以会在宿主机内存可用的情况下还是去调大内存,如果调小的话;对象回收不了也很容易造成内存溢出、风险更大。

G1
  • G1 逻辑上区域还是一样的。新生代(包含三个区域(Eden/S0/S1区域)、老年代(old)但是他的结构发生了巨大的变化;就是说他把内存分为2048个内存块;每个块的大小在[1M,32M]之间。
  • 分成块的主要目的是可以控制扫描范围、这是G1核心功能;我们是可以设置每次GC的最大毫秒数、G1会根据我们设置的毫秒数来决定每次去回收多少个region块。
  • G1的优点就是更灵活了、GC耗时可配置;最大可能降低了扫描范围,虽然也有STW问题;但是他先圈了一块region再去回收(有限使用比较多的region区域)。更精细、延迟更低了,也没有垃圾碎片的问题;不像CMS那样每次还要STW整个堆区域;还有垃圾碎片的问题。
  • 但是G1 GC的频率更高了。对CPU使用也比较频繁;因为每次GC的区域比较小。CMS GC耗时不可预测、CPU使用率低、在能够容忍GC STW还是不错的选择,还有就是G1的新版对STW的优化可能要收费。


    image.png
三、jdk7/jdk8之间的区别
  • 永久代 JDK7 存储的信息比较少、方法、常量等;基本不会触发Full GC、JDK8使用了元空间后;实际上默认共享了物理内存、也就是说物理内存有多大;就可以使用多大;充分降低了JVM可能会造成的GC影响;但一般都会去设置元空间大小为了避免对宿主机内存造成影响;影响其他进程。
四、排查高耗GC的方式
  • 通过top 看高耗线程、线程ID 转换16进制 、再通过jstack 打印堆栈信息、找到16进制的代码块。
  • 通过jmap gcutil 查看内存分配、内存实时运行状态 来判断。很多时候内存溢出都会触发大量的Full GC通过gcutils 可以找到判断信息。有些情况并没有代码抛异常、就是触发Full GC 导致系统卡顿、这个时候查询JVM内存状态是非常好的手段。
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1.GC基本概念 在java中,程序员是不需要显式的去释放一个对象的内存的,而是由虚拟机自行执行。在JVM中有一个...
    hadoop_a9bb阅读 393评论 0赞 0
  • JVM内存结构简介(jdk1.8) JVM层的GC调优是生产环境上必不可少的一个环节,因为我们需要确定这个进程可以...
    Lemonrel阅读 445评论 0赞 0
  • Jdk垃圾收集器迭代版本:jdk1.7 默认垃圾收集器Parallel Scavenge(新生代)+Paralle...
    滔滔逐浪阅读 608评论 0赞 3
  • 1、JVM定义 Java虚拟机包括程序计数器(线程私有),虚拟机栈(线程私有),本地方法栈(线程私有),Java堆...
    学海一乌鸦阅读 897评论 0赞 0
  • 许多高级编程语言都带有自动垃圾回收特性,以将程序员从繁琐复杂的内存分配和释放工作中解脱。本文将概述常见的垃圾回收算...
    kelgon阅读 2,153评论 2赞 52

友情链接更多精彩内容