JVM调优 学习笔记
2024-07-15 11:29:00 0 举报
AI智能生成
JVM调优关键知识点
作者其他创作
大纲/内容
数据类型
基本类型
基本类型的变量保存原始值,即:他代表的值就是数值本身
基本类型包括:byte,short,int,long,char,float,double,Boolean,returnAddress
引用类型
引用类型的变量保存引用值。“引用值”代表了某个对象的引用,而不是对象本身,对象本身存放在这个引用值所表示的地址的位置。
引用类型包括:类类型,接口类型和数组
栈
栈是运行时的单位
栈解决程序的运行问题,即程序如何执行,或者说如何处理数据
一个线程就会相应有一个线程栈与之对应
main函数就是栈的起始点,也是程序的起始点
在栈中,一个对象只对应了一个4btye的引用
堆
堆是存储的单位
堆解决的是数据存储的问题,即数据怎么放、放在哪儿
堆是所有线程共享的
一个空Object对象的大小是8byte
一个基本类型包装类的大小至少是16byte
堆栈分离的优点
第一,从软件设计的角度看,栈代表了处理逻辑,而堆代表了数据。这样分开,使得处理逻辑更为清晰
第二,堆与栈的分离,使得堆中的内容可以被多个栈共享
这种共享提供了一种有效的数据交互方式
堆中的共享常量和缓存可以被所有栈访问,节省了空间
第三,堆中的对象是可以根据需要动态增长的,因此栈和堆的拆分,使得动态增长成为可能,相应栈中只需记录堆中的一个地址即可
第四,面向对象就是堆和栈的完美结合
堆中存的是对象。栈中存的是基本数据类型和堆中对象的引用
不把基本类型放堆中因为其占用的空间一般是1~8个字节,需要空间比较少,而且因为是基本类型,所以不会出现动态增长的情况(长度固定)
程序运行可以没有堆,但是不能没有栈。而堆是为栈进行数据存储服务,说白了堆就是一块共享的内存。堆和栈的分离才使得Java的垃圾回收成为可能
引用类型
强引用
软引用
弱引用
虚引用
JVM内存分布
垃圾回收器
基本回收算法
引用计数(Reference Counting)
标记-清除(Mark-Sweep)
复制(Copying)
标记-压缩(Mark-Compact)
分区对待算法
增量收集算法(Incremental Collecting)
分代收集算法(Generational Collecting)
新生代使用复制算法
老年代使用标记压缩算法
系统线程策略
串行收集
适用情况:数据量比较小(100M左右);单处理器下并且对响应时间无要求的应用。
缺点:只能用于小型应用
可以使用-XX:+UseSerialGC打开
并行收集
适用情况:“对吞吐量有高要求”,多CPU、对应用响应时间无要求的中、大型应用。举例:后台处理、科学计算。
缺点:垃圾收集过程中应用响应时间可能加长
使用-XX:+UseParallelGC.打开
并发收集
适用情况:“对响应时间有高要求”,多CPU、对应用响应时间有较高要求的中、大型应用。
使用-XX:+UseConcMarkSweepGC打开
垃圾回收面临的问题
如何区分垃圾
如何处理碎片
如何解决同时存在的对象创建和对象回收问题
分代垃圾回收
年轻代(Young Generation)
Eden区(1个)
Survivor区(2个)
年老代(Old Generation)
持久代(Permanent Generation)
触发垃圾回收
Scavenge GC
Full GC
年老代被写满
持久代被写满
System.gc()被显示调用
上一次GC之后Heap的各域分配策略动态变化
典型配置
堆大小设置
回收器选择
响应时间优先的并发收集器
吞吐量优先的并行收集器
辅助信息
-XX:+PrintGC:打印每次GC的信息
-XX:+PrintGCDetails:打印每次GC的信息
-XX:+PrintGCTimeStamps:打印每次GC的时间戳
-XX:+PrintGCApplicationConcurrentTime:打印最后一次暂停之后所经过的时间
-XX:+PrintGCApplicationStoppedTime:打印GC时应用暂停时间
-XX:PrintHeapAtGC
-Xloggc:filename
常见配置
参数设置
-Xms:堆初始值
-Xmx:堆最大值
-Xss:线程栈大小
-Xmn:年经代初始值和最大值
-XX:NewSize=n:年轻代初始值
-XX:MaxNewSize=n:年轻代最大值
-XX:PermSize=n:持久代初始值(JDK8已废除)
-XX:MaxPermSize=n:持久代最大值(JDK8已废除)
-XX:MetaspaceSize=n:元数据空间初始值(JDK8新新增,并移除了持久代->XX:PermSize))
-XX:MaxMetaspaceSize=n:元数据空间最大值(JDK8新新增,并移除了持久代->XX:MaxPermSize)
-XX:NewRatio=n:设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4
-XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5
收集器设置
-XX:+UseSerialGC:设置串行收集器
-XX:+UseParallelGC:设置并行收集器
-XX:+UseParalledlOldGC:设置并行年老代收集器
-XX:+UseConcMarkSweepGC:设置并发收集器
并行收集器设置
-XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数。并行收集线程数。
-XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间
-XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)
并发收集器设置
-XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况。
-XX:ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时,使用的CPU数。并行收集线程数
调优总结
年轻代大小选择
响应时间优先的应用:尽可能设大,直到接近系统的最低响应时间限制(根据实际情况选择)。在此种情况下,年轻代收集发生的频率也是最小的。同时,减少到达年老代的对象。
吞吐量优先的应用:尽可能的设置大,可能到达Gbit的程度。因为对响应时间没有要求,垃圾收集可以并行进行,一般适合8CPU以上的应用。
年老代大小选择
响应时间优先的应用:年老代使用并发收集器,所以其大小需要小心设置,一般要考虑并发会话率和会话持续时间等一些参数
吞吐量优先的应用:一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代
较小堆引起的碎片问题
G1垃圾回收算法
分代垃圾回收存在的缺点:Full GC所带来的应用暂停
G1收集器适用于大容量内存的多核服务器,它在满足垃圾回收暂停时间目标的同时,以最大可能实现高吞吐量
G1回收算法的优点
支持很大的堆
高吞吐量
支持多CPU和垃圾回收线程
在主线程暂停的情况下,使用并行收集
在主线程运行的情况下,使用并发收集
实时目标
可配置在N毫秒内最多只占用M毫秒的时间进行垃圾回收
G1回收算法的缺点
相对传统的分代回收算法,在性能上会有一些损失
G1算法回收步骤
初始标记(Initial Marking)
并发标记(Concurrent Marking)
最终标记暂停(Final Marking Pause)
存活对象计算及清除(Live Data Counting and Cleanup)
JVM调优工具
jconsole: JDK自带,功能简单,但是可以在系统有一定负荷的情况下使用。对垃圾回收算法有很详细的跟踪。
VisualVM:JDK自带,功能强大,与JProfiler类似。推荐
jProfiler:商业软件,需要付费。功能强大
JVM自带工具
jstat:对进程的资源和性能进行实时的命令行的监控,包括了对进程的classloader,compiler,gc情况;
jmap:打印进程的堆内详情、产生对象数量及内存使用情况;可用于检查内存泄露、对象不合理创建及销毁问题
jstack:打印进程的栈信息;可以确定性能阻塞的类和方法
jps:查看所有的jvm进程,包括进程ID,进程启动的路径等等
jinfo:观察进程运行环境参数,包括Java System属性和JVM命令行参数
JVM调优点
查看堆空间大小分配(年轻代、年老代、持久代分配)
垃圾回收监控(长时间监控回收情况)
线程信息监控:系统线程数量
线程状态监控:各个线程都处在什么样的状态下
线程详细信息:查看线程内部运行情况,死锁检查
CPU热点:检查系统哪些方法占用了大量CPU时间
内存热点:检查哪些对象在系统中数量最大
类生命周期
加载
验证
准备
解析
初始化
使用
卸载
0 条评论
下一页