jvm基础篇2

简述

  • jvm性能调优 为了减少full gc频率以及full gc时间


    jvm基础篇2_第1张图片
    jvm图解.jpg

工具使用总结

  • 使用jps查看java进程

  • jmap -heap pid查看整个jvm内存状态

  • jmap -dump:format=b,file=/my.dump pid 导出pid进程的java程序的整个JVM信息,可以使用MAT分析

  • jstack pid 分析堆栈信息

  • jstat -gcutil pid 1000 20 每秒输出gc情况,输出20次, s1 表示其中一个survivor, eden表示eden区,o表示老年代,p表示持久代,YGC年轻代gc次数,YGCT表示年轻代gc时间,FGC表示full gc次数,FGCT表示full gc总时间。


    gc情况统计.png
  • 当然如果打开了gc日志打印就可以看Gc日志(-XX:+PrintGCDetails) ; PS是Parallel Scavenge收集器的缩写,它配套的新生代称为PSYoungGen, ParOldGen----Parallel Scavenge收集器配套的老年代


    jvm基础篇2_第2张图片
    gc日志.png
  • 注本地可以使用jvisualvm.exe分析


jvm知识总结

jvm内存区域
  • 堆内内存

    1. 程序计数器: 字节码的位置指示器。分支、循环、跳转、异常处理和线程恢复等基础功能都需要依赖这个计算器来完成。
    2. 虚拟机栈 由一个个栈帧组成,程序结束完毕这部分自动回收,栈帧主要由 局部变量表,操作数栈,动态链接(多态),出口记录(异常时打印堆栈)
    3. 本地方法栈 主要由native方法调用
    4. 堆内存 垃圾回收主要区域
    5. 方法区 静态变量,常量池之类的,垃圾回收也会回收这块区域,比如一些不用的变量之类的。


      jvm基础篇2_第3张图片
      堆内内存.png
  • 直接内存
    1.jni调了c后,占用的是c代码里规定的内存。如果c直接用malloc分配内存,那jvm是管不到的
    2.nio的io操作很多使用了堆外内存,这样就不用在直接内存和非直接存来回复制。jvm直接管理堆内内存,直接内存jvm是不能直接管理的。
    3.jvm很多使用DirectByteBuff作为直接内存的引用好处是不用在堆内内存跟直接内存直接来回复制

垃圾回收算法
  • 可达性分析(判断对象已死): 根部是GC roots,如果引用链不可达到GC root则表示对象已死,可作为GC roots对象有,方法区中静态变量,常量的引用,虚拟机栈中引用,本地方法jni引用
  • 标记清除算法: 先标记Gc root可达对象,再对gc root不可达对象进行清楚
  • 标记整理算法: 与标记清除不同,它会清除内存碎片
  • 复制算法: 将每个活的对象复制到另一个区域,然后全部清除该区域对象。
  • 分代收集算法: 年轻代用复制算法,因为每次存活对象少。 年老代用标记清楚或者标记整理算法。
垃圾收集器
  • 所有的垃圾收集器


    jvm基础篇2_第4张图片
    垃圾收集器.png
  • Serial收集器(复制算法): 新生代单线程收集器
  • Serial Old收集器(标记-整理算法)
    老年代单线程收集器,Serial收集器的老年代版本。
  • ParNew收集器(停止-复制算法): 新生代收集器多线程版本与CMS配合使用
  • CMS(Concurrent Mark Sweep)收集器(标记-清理算法)
    老年代收集器,高并发、低停顿,追求最短GC回收停顿时间,cpu占用比较高,响应时间快,停顿时间短,多核cpu 追求高响应时间的选择。缺点无法处理浮动垃圾(在并行清理时产生的垃圾),可能出现Concurrent Model Failure失败而导致另一次Full GC的产生,可能产生内存碎片(可通过参数设置碎片自动整理)。垃圾回收流程:
    1.初始标记:标记GC Roots能直接到的对象。速度很快但是仍存在Stop The World问题。
    2.并发标记:进行GC Roots Tracing 的过程,找出存活对象且用户线程可并发执行。
    3.重新标记:为了修正并发标记期间因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录。仍然存在Stop The World问题。
    4.并发清除:对标记的对象进行清除回收。
  • Parallel Scavenge收集器(停止-复制算法): 新生代算法,追求高吞吐量
  • Parallel Old收集器(停止-复制算法) Parallel Scavenge收集器的老年代版本,并行收集器,吞吐量优先
  • G1收集器 特点
    1. G1 的主要关注点在于达到可控的停顿时间,在这个基础上尽可能提高吞吐量,这一点非常重要。
    2. G1并不会等内存耗尽(串行、并行)或者快耗尽(CMS)的时候开始垃圾收集,而是在内部采用了启发式算法,在老年代找出具有高收集收益的分区进行收集。
    3. G1采用内存分区(Region)的思路,将内存划分为一个个相等大小的内存分区,回收时则以分区为单位进行回收,存活的对象复制到另一个空闲分区中
    4. G1虽然也是分代收集器,但整个内存分区不存在物理上的年轻代与老年代的区别,也不需要完全独立的survivor(to space)堆做复制准备。G1只有逻辑上的分代概念.
    5. G1的收集都是STW的,但年轻代和老年代的收集界限比较模糊,采用了混合(mixed)收集的方式。即每次收集既可能只收集年轻代分区(年轻代收集),也可能在收集年轻代的同时,包含部分老年代分区(混合收集),这样即使堆内存很大时,也可以限制收集范围,从而降低停顿。

深入

JVM 里 new 对象时,堆会发生抢占吗?你是怎么去设计JVM的堆的线程安全的?

  • 不会,每个线程在Java堆中预先分配一小块内存,然后再给对象分配内存的时候,直接在自己这块"私有"内存中分配,当这部分区域用完之后,再分配新的"私有"内存。在对于TLAB(Thread Local Allocation Buffer)的分配过程,还是需要进行同步控制的

参考文献

  • 内存泄露分析总结和tomcat调优
  • system.gc()和-XX:+DisableExplicitGC启动参数,以及DirectByteBuffer的内存释放
  • JVM 参数详解
  • CMS垃圾回收器详解
  • JVM优化之调整大内存分页(LargePage)
  • vm垃圾回收器(终结篇)
  • 扒一扒JVM的垃圾回收机制
  • g1垃圾收集器简介

参考2

  • Java GC 变量含义(S0 S1 E O P YGC YGCT FGC FGCT GCT)详解
  • tomcat服务器解析(二) --- Endpoint
  • 内存分析工具MAT
  • jstack在线分析
  • java内存分析工具 jmap,jhat及dump分析
  • JVM学习笔记——jhat的使用
  • 通过jstack与jmap分析一次cpu打满的线上故障
  • MAT使用教程
  • Shallow heap & Retained heap

你可能感兴趣的:(jvm基础篇2)