Skip to content

Latest commit

 

History

History
95 lines (73 loc) · 3.44 KB

从Jvm内存模型到调优.md

File metadata and controls

95 lines (73 loc) · 3.44 KB

从 Jvm 内存模型到调优


Jvm 内存模型

  • 内存模型
    • 运行时数据区
      • 堆内存,虚拟机栈,本地方法栈,程序计数器,方法区
    • Jvm 内存模型
      • 新生代(1-1.5)
        • 就是将新创建的对象放在这里,分配比例按8:1:1分配成 eden 区和sur0/1区,采用复制清除算法
      • 老年代(2-3)
        • 在新生代中存留足够次数的对象就会放到老年代,也有可能会作为担保分配到老年代,采用整理算法
      • 永久代(1.2-1.5)
        • 类的源信息和常量数据会存储在这里
  • 双亲委派
    • 在加载类的时候先委派给他的父类加载器进行加载,如果父类不能加载的时候才自己加载。
      • 这样加载类就会有层级关系
      • 也可以防止底层类被篡改
  • 对象的分配流程
  • GC
    • 如何判断对象已死
      • 引用计数:通过计算对象之间的引用数量来判断是否死亡,问题:循环引用
      • 根节点搜索:通过分析栈和方法区中的数据有没有指向该对象来判断对象是否死亡
    • 常见的GC算法
      • 标记清除:标记之后直接及逆行清理,这样会造成大量的碎片空间
      • 标记整理:为了解决标记清除带来的大量碎片空间问题,采用整理清除完的空间。
      • 标记复制:大量的对象移动不如复制的效率高。
    • GC的类型
      • MinorGC:代表新生代进行GC操作
      • MajorGC:代表了老年代进行GC操作
      • FullGC:上述两种GC的总和
  • 垃圾回收器
    • Serlizeable:该种垃圾回收器的特点是采用单线程进行垃圾回收操作,同时在回收期间暂停其他用户线程的操作
    • Prepal:该种垃圾回收器的特点是采用多线程进行垃圾回收操作,同时也是在回收期间暂停其他用户线程的操作
    • CMS:这种垃圾回收期在标记阶段采用和用户线程并行操作,标记结束后启动多线程进行回收
    • G1:采用分块的模式,来减少 fullGC 的操作。

常见调优的流程

  1. 首先查看当前机器的状态

    • top:用来查看当前机器cpu / 内存 状态,如果出现异常可以通过 jstack pid 打印线程信息
    • df -h:查看磁盘的状态
  2. 查看当前 Jvm 的垃圾回收器类型,并查看配置

    • java -XX:+PrintCommandLineFlags -version
    • jstat -gcutil pid 1000 动态打印日志
    • jmap -heap pid 查看堆内存使用情况
  3. 配置 Jvm 打印对应的 GC 日志

    #常用配置
    -Xms30m 初始堆空间
    -Xmx30m 最大堆空间
    -Xmn10m 新生代空间
    -Xss2m 栈大小
    #输出日志
    -XX:+PrintGCTimeStamps
    -XX:+PrintGCDetails
    -Xloggc:/dir/gc.log
    #日志文件控制
    -XX:-UseGCLogFileRotation
    -XX:GCLogFileSize=8k
    
  4. 查看 GC 日志,分析 GC 日志

  5. 通过 Jstack 查看是否有死锁

  6. 配置 OOM 的时候保存内存快照

    -XX:+HeapDumpOnOutOfMemoryError
    -XX:HeapDumpPath=/dir/error.hporf
    
  7. 常见的推荐配置大小

    • 确定活跃数据,活跃数据为运行稳定后Full GC后老年代的大小。

      名称 倍数
      总大小 3-4
      新生代 1-1.5
      老年带 2-3
      永久代 1.2-1.5(Full GC后永久代的大小)