# jvm内存模型
- 程序计数器
- 虚拟机栈
- 本地方法栈
- 堆
- 常量池(方法区)
# jVM内存管理
- java程序可管理内存包括:堆栈
# 虚拟机栈
- 线程启动时创建。虚拟机栈,包含多个栈帧,栈帧对应的就是调用的方法,每一个方法从调用到返回结果的过程,就是栈帧入栈和出栈的过程.
- 栈内存的大小,是固定的。可通过
-Xss参数
指定 - 运行时,成员变量和对象本身不放在栈帧中,但是它们的引用会存放在栈中。
- 栈的变量随着变量作用域的结束而释放,不需要jvm垃圾回收机制回收。
- 栈内存的大小,是固定的。可通过
# 栈优点
- 栈帧之间数据不能共享,但同一个栈帧内的数据是可以共享的。
- 存取速度快,仅次于寄存器;
# 栈缺点
- 数据大小和生存期是确定的,缺乏灵活性.
# 堆
- 虚拟机启动时创建,被虚拟机内的所有线程共享;
- 堆的唯一目的就是存放对象实例;
- 堆是垃圾收集器活动的主要区域;
# 代际堆
- 由于现代收集器基本都是采用的分代收集算法,所以java堆可以细分为年轻代和老年代;
- 新生代由Eden Space和两块大小相同的Survivor Space,通常又称S0和S1,或From和To.
- 通过参数
-Xmn
可指定新生代大小 - 通过参数
-XX:SurvivorRation可调整Eden和Survivor的大小
- 通过参数
- 老年代用于存放经过多次新生代GC仍然存活的对象.新建的大对象也可能直接进入老年代.
# 方法区
- 存储
class类
的元数据信息,包括类的基本信息,字段信息,方法信息、类静态变量等; - 方法区存储在永久代中。
# jvm参数调优
# 堆调整策略
- jvm启动时,默认申请的最小堆内存为物理内存的1/64且小于1G;申请的最大堆内存默认为物理内存的1/4且小于1G;可通过
-Xms(最小值)
,-Xmx(最大值)
设置 - 默认空余堆内存**小于40%时,会增大到最大堆内存大小;默认空余堆内存大于70%**时,会减小到最小堆内存大小;可通过:
-XX:MinHeapFreeRation=
,-XX:MaxHeapFreeRation=
来指定比例; - 对于运行系统,为避免频繁的调整Heap大小,通常-Xms与-Xmx的值设成一样
# GC策略
注意,垃圾回收时,会触发stop-the-world,即暂停应用程序.
- 单线程收集器
- client模式下的默认方式;
- 通过参数:
-XX:+UseSerialGC
强制指定
- 并行收集器
- server模式下的默认方式
-XX:ParallelGCThreads=20
,设置并行收集的线程数目-XX:+UseParallelGC
,设置年轻代为并行收集-XX:+UseParallelOldGC
,设置老年代为并行收集-XX:MaxGCPauseMillis=100
,设置暂停时间,如果年轻代回收无法满足此要求,JVM会自动调整年轻代大小
- 并发收集器
- 与并行的区别是,只有在初始标记和二次标记时,需要stop-the-world。但收集时间很长,不能等年轻代满后才开始清理.
- 根据官方文档,该模式需要在多CPU的情况下,才能发挥作用。一个CPU时,不如单收集器,两个CPU时,也提高不大.
# GC触发条件
- 当eden区对象空间大于S0的空间时,发生minor gc,对整个
s0,s1
进行复制算法垃圾回收,并将部分对象转到Old Generation
- 当新生代满了(eden+s0大于oldGeneration时),发生major gc或者full gc,即对新生代和老年代都进行回收
# GC参数调优建议
新生代大小建议
- 响应时间优先的应用,年轻代尽可能设大(直到达到应用系统的最低响应时间限制),因为会减少
minor gc
的次数。 - 吞吐量优先的应用,年轻代尽可能设置大,可能达到Gbit的程度,因为对响应时间没有要求,垃圾收集可以并行进行,一般适合8CPU以上的应用
- 响应时间优先的应用,年轻代尽可能设大(直到达到应用系统的最低响应时间限制),因为会减少
老年代大小建议
响应时间优先的应用,要综合并发会话频率、持续时间等参数
吞吐量优先的应用,一般有一个很大的年轻代和一个较小的老年代
老年代较小时,容易引起碎片问题。