jvm运行时内存空间:
方法区 jvm虚拟机栈 本地方法栈
{ java堆 } 程序计数器
| |
| |
执行引擎---->本地接口 --->本地方法库
程序计数器:
进程切换时用户保留现场
jvm虚拟机栈:
保存参数,局部变量,中间计算过程和其他数据。
每个方法被执行时多会创建一个栈帧(每个方法执行,对应一个栈帧在虚拟机栈中冲入栈道出栈的过程)
本地方法栈:
和java虚拟机栈作用类似(不同点是:虚拟机执行java方法时使用的)
jvm堆:
存放对象和实例
当前主流的虚拟机堆内存都是按照可扩展来实现的(通过-Xmx和-Xms控制)。
如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。
年轻代+年老代+持久代的部分
方法区:"持久代的部分"(Permanent Generation)
用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等
堆内存结构:
Young Old Permanent
Eden 、 Survivor
Eden 、 From 、 To
非堆内存:
(Permanent持久代(部分在堆内存中))
-Xss 栈内存:
(默认1M)(每线程使用)
-Xms:
star heap (默认物理内存的1/64 <1GB )
-Xmx:
max heap (默认物理内存1/4 <4GB)
建议-Xms = -Xmx 避免gc后,调整堆大小,减少系统内存分配开销
-Xmn:
young区大小 (默认堆的3/8 )
-XX:NewRatio:
年轻代/年老代 的比值
设置了Xms=Xmx的情况下该参数不用设置
-XX:SurvivorRatio:
E / S 的比值 (默认是8)
old区:
(-Xmx 减去 -Xmn 减去 持久代)
年轻代中经过垃圾回收没有回收掉的对象被复制到年老代
年老代存储对象比年轻代大,而且不乏大对象,eg:缓存、、
-XX:PretenureSizeThreshold=1024(默认0,多进入E区)
创建的对象超过1024时直接进入年老代
弱引用对象:
新生代未回收的对象大于年老代的值就会回出现FGC
FGC:
回收整个堆内存,然后把新生代未回收的值放入堆内存
强引用对象:
出现FGC,直接OutOfMemor
持久代:(方法区)
存放class、Method元信息、类、方法
-XX:PermSize 初始大小
-XX:MaxPermSize 最大值
建议 -XX:PermSize等于-XX:MaxPermSize
一般设置为128M (以最快的方式做好事情:监控该值,发现不足,调大(要停机))
调优:
所有的调优多需要有个指标,不然多是扯淡。
jvm垃圾回收机制:
垃圾收集算法:
1、引用计数(被抛弃了)
2、根搜索算法
jvm垃圾回收算法:
1、复制算法
E-->S (新生代大部分是不存活的了)
从根集合扫描,将存活的对象复制到一块新的没有使用的空间,清楚不存活的
2、标记清除算法
适合老生代回收
从根集合扫描,对存活对象进行标记后,再扫描整个空间未被标记的对象进行回收,并更新指针进行对象移动(产生成本),解决内存碎片问题。
3、标记整理压缩算法
垃圾回收器:
新生代:(复制算法)
Serial 、 ParNew 、Parallel Scavenge
年老代:(标记清除算法、标记整理压缩算法)
CMS 、 Serial old 、Parallel old
串行回收:
gc单线程内存回收,会暂停所有的用户线程 (没有多线程交互单线程回收更高效) serial串行回收器
-XX:+UseSerialGC 开启 (新生代和年老代开启方法一样)
开启后使用:Serial New + Serial Old 组合回收
并行回收:
多个gc进程并行工作,但此时用户线程是暂停的, Parallel收集器
-XX:+UseParNewGC 开启ParNew
开启后:新生代使用并行回收器,年老代使用串行回收器
-XX:ParallelGCThreads 指定线程数(最好与cpu核心相当)
-XX:+UseParallelGC 开启Parallel Scavenge
开启后:使用Parllel Scavenge + Serial Old 组合回收
-XX:GCTimeRatio 设置用户执行时间占总时间百分比,默认99
-XX:MaxGCPauseMillis 设置GC最大停顿时间
-XX:+UseParallelOldGC 开启Parallel Old回收
开启后使用:Parallel Scavenge + Parallel Old 组合回收
并发回收:
用户线程和gc线程同时执行(不一定是并行),不需要停止用户线程(暂停非常短) CMS收集器(并发标记清除)
-XX:+UseConcMarkSweepGC 开启CMS
开启后使用:ParNew + CMS + Serial Old
(Serial Old 作为CMS出现问题后的备用收集器)
两种回收失败:
CMS还没有到达回收的阈值,新生代存活对象过来了,但是年老代空间不足(触发FGC)。
CMS回收过程中(未回收完),新生代存活对象过来了(触发FGC),
-XX:ParallelCMSThreads 设置线程数(默认:(ParallelGCThreads+3)/4)
IO密集型:cpu核数*2+1
cpu密集型:cpu核数+1
-XX:CMSlnitiatingOccupancyFraction
设置在年老代被使用多少后发起垃圾回收(默认68%)
-XX:+UseCMSCompactAtFullCollection
由于CMS收集器会产生碎片,设置后再CMS垃圾回收后进行一次内存碎片整理过程
-XX:+CMSFullGCBeforeCompaction
设置CMS在收集若干次后再进行一次内存整理
-XX:CMSlnitiatingPermOccupancyFraction
设置Perm Gen使用达到多少是触发(默认92%)
性能指标:
吞吐量:
应用花在非GC上的时间百分比
GC负荷:
应用花在GC上的时间百分比
暂停时间:
GC暂停时间
GC频率:
GC发生的频率
反应速度:
对象回收时间
年轻代大小选择:
响应时间优先应用
尽可能设大,直到接近系统最低响应时间
吞吐量优先的应用:
尽可能大
避免设置过小:
YGC频繁
年老代大小选择:
响应时间优先:
CMS