• [Java] JVM


     目标

    • 熟悉GC常用算法,熟悉常见垃圾收集器,具有实际JVM调优实战经验

    组成

    • 类装载子系统
    • 运行时数据区(内存模型)
    • 字节码执行引擎

    内存区域

      • 存放new出来的对象
      • 所有线程和方法共享
    • 栈(线程栈)
      • JVM为每个线程分配一个独立的栈空间,存储局部变量
      • 栈帧:每个方法对应一块栈帧,存放方法的局部变量,方法运行完销毁
        • 局部变量表:为变量分配内存空间,变量指向堆中的对象(地址)
        • 操作数栈:存放临时数据
        • 动态链接:实现多态
        • 方法出口:调用函数后返回原位置继续执行
    • 本地方法栈:本地c语言写的方法在运行过程中需要的运行空间,为调用本地方法的线程分配
    • 程序计数器(pc Register):线程正在运行的代码的行号,每个线程独有,实现多线程
    • 方法区(元空间)
      • 常量
      • 静态变量(static)
      • 类信息

    gc(Garbage Collect)

    • 垃圾:没有引用指向的对象
    • C++:new(),delete(),自己清理垃圾
    • 找垃圾算法
      • reference count(引用计数):不能解决环形引用
      • root searching(根可达算法)
        • 从gc root出发,向下搜索引用的对象,找到的对象标记为非垃圾对象
        • 存入S0区,并回收Eden中的对象
      • 哪些是根  
        • JVM stack
        • native method stack
        • run time constant pool
        • static reference in method area
        • Clazz
    • 回收算法
      • Mark-Sweep(标记清除):会产生碎片
      • Copying:内存浪费
      • Mark-Compact:需移动对象,效率比Copying低
    • 发展路线
      • 随着内存增大而演进(先脉络,后细节)
      • 从分代算法演化到不分带算法
      • hotspot
        • 工作在年轻代的GC
          • Serial:a stop-the-world(STW), copying collector which uses a single GC thread(几M~几十M)
          • ParNew:PS,可配合CMS
          • Parallel Scavenge:a STW, copying collector which uses multiple GC threads(几个G,1.8默认)
        • 工作在老年代的GC
          • CMS:初始标记(STW,找gc root,快)->并发标记(不用STW,慢)->重新标记(STW,快)->并发清理(承上启下,三色标记+写屏障,几十个G)
          • Seril Old:STW,single GC thread,用 mark-sweep 或 Mark-Compact
          • Parallel Old(1.8默认 PS + PO/Parallel GC,几百个参数)
        • G1
          • Garbage First(先清理垃圾多的块,几十个参数)
          • 逻辑分代,物理不分代(上百G)
          • 分区回收
          • 三色标记+SATB+写屏障
        • ZGC Shenandoah
          • 逻辑,物理都不分代(4T)
          • 基于C4(None STW)
          • ColoredPointers,颜色指针+读屏障
        • Epsilon
          • 调试,确认不用GC参与就能干完活
    • 分区算法
      • 80%对象“朝生夕死”
      • 找出eden区的幸存对象,复制到s0,清除剩余对象
      • 找出eden区、s0区的幸存对象,复制到s1,清除剩余对象
      • s0,s1互换,重复上一步
      • 15次(不同GC不一样)不死的对象,复制到老年区(如缓存对象,spring中的bean等)
      • 老年区满,full gc,整体回收
    • 概念
      • YGC:minor gc
      • FGC:full gc,major gc
      • TLAB:thread local allocation buffer,每个线程专属的内存空间,属于eden
      • 标记失误:垃圾在标记后,清除前被引用
      • 分代年龄:放在对象头中,每次minor gc后没有被清除,分代年龄+1
      • 对象头(Object Header):并发编程、JVM基础
      • 类装载子系统:装载类到本地方法栈
      • 字节码执行引擎:修改程序计数器,执行方法区中的class文件

    CMS

    G1

     

    调优

    • 目的: 减少STW(Stop The World),即JVM触发full gc会暂停所有其他线程,造成卡顿
    • STW的目的:线程停止后,gc root可能消失,导致原来不是垃圾的对象变成垃圾对象
    • 对象动态年龄判断机制
    • 手段
      • 调吞吐量
      • 调响应时间
    • OOM(out of memory):如何通过调优解决

    实例1

    • 8G内存,degn
    • 每日用户点击量上亿
    • 日活500w左右
    • 京东、拼多多等
    • 每秒几十单
    • 大促时80%的订单在几分钟产生
    • 每秒1000多单
    • 每个订单对象1KB
    • 每秒300KB订单对象
    • 下单涉及其它对象,如库存,优惠券,积分等,再放大20倍
    • 6M/s对象放入堆中
    • 其他操作再放大10倍
    • 60M/s对象放入eden,1s后都变成垃圾()
    • 10s放满 
    • gc root:
    • old区几分钟放满,执行full gc,1s后变成垃圾(不应该放在old)
    • 将eden调为1.6G,25s填满
    • 调优后,不会发生full gc

    调优前

    调优后

     

    实例2

    中间件性能调优

    工具

    • arthas

    参考

    • javap-c:反汇编
    • JVM指令手册
  • 相关阅读:
    PHP
    Python语言特性
    Selenium2+python自动化
    Linux命令--系统管理
    Linux命令--网络管理
    Linux命令--压缩解压(简化版)
    Linux--压缩解压命令
    Linux命令--用户管理
    Linux命令--获取帮助
    Linux命令--权限管理
  • 原文地址:https://www.cnblogs.com/cxc1357/p/12521570.html
Copyright © 2020-2023  润新知