组成
- 类装载子系统
- 运行时数据区(内存模型)
- 字节码执行引擎
内存区域
- 堆
- 栈(线程栈)
- JVM为每个线程分配一个独立的栈空间,存储局部变量
- 栈帧:每个方法对应一块栈帧,存放方法的局部变量,方法运行完销毁
- 局部变量表:为变量分配内存空间,变量指向堆中的对象(地址)
- 操作数栈:存放临时数据
- 动态链接:实现多态
- 方法出口:调用函数后返回原位置继续执行
- 本地方法栈:本地c语言写的方法在运行过程中需要的运行空间,为调用本地方法的线程分配
- 程序计数器(pc Register):线程正在运行的代码的行号,每个线程独有,实现多线程
- 方法区(元空间)
gc
- 可达性分析算法:从gc root出发,向下搜索引用的对象,找到的对象标记为非垃圾对象,存入S0区,并回收Eden中的对象
- 分代年龄:放在对象头中,每次minor gc后没有被清除,分代年龄+1
- 对象头(Object Header):并发编程、JVM基础
- 类装载子系统:装载类到本地方法栈
- 字节码执行引擎:修改程序计数器,执行方法区中的class文件
- Eden区满后,字节码执行引擎对Eden区执行minor gc
- s0和s1中交替存放
- 对象15次minor gc后还在Servivor区,进入老年代,如缓存对象,spring中的bean等
- 老年代放满后,触发字节码执行引擎的full gc,回收所有对象,OOM


调优
- 目的: 减少STW(Stop The World),即JVM触发full gc会暂停所有其他线程,造成卡顿
- STW的目的:线程停止后,gc root可能消失,导致原来不是垃圾的对象变成垃圾对象
- 对象动态年龄判断机制
实例
- 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


调优前

调优后


中间件性能调优
参考
[Java] JVM
原文:https://www.cnblogs.com/cxc1357/p/12521570.html