文章目录
- JVM调优
- 调优描述
- 1. 背景
- 2. JVM调优的过程
- 3. 性能监控复盘
- 1. 性能监控工具
- 2. 性能指标
- 3. 性能分析
- 4. 性能调优
- 5. 垃圾回收器选择
- 6. 运行时参数的设定
- 7. 实战案例
- 1.单体应用在大内存硬件上部署
- 2. 集群同步导致内存溢出
- 3. 堆外内存导致溢出的错误
- 4. 外部命令导致系统缓慢
- 5. 服务器虚拟机进程崩溃
- 6. 不恰当的数据结构导致内存占用过大
- 7. 由Windows虚拟机导致长时间停顿(存在问题)
- 8. 由安全点导致的长时间停顿
- 实战:Eclipse运行速度调优
- 0. 使用工具
- 1. 初始状态
- 2. 解决方案
- 3. 总结
JVM调优
调优描述
1. 背景
2. JVM调优的过程
3. 性能监控复盘
- 性能对比
- 性能监控、分析、调优的经验总结
- 对软件设计和硬件要求的总结
1. 性能监控工具
- jps [-v] [-l] [-q] [-m]
- -v : 打印日志信息
- -l : 打印详细信息
- -q : 打印简略信息
- -m:输出传给main类的参数
- root:node2:支持远程连接 [主机名:端口号]
- jstat -option :产看JVM的统计信息
- option参数和普通的参数
- 普通参数
- inteval
- count
- -t : 程序运行的时间
- -h
- 顺序 jstat -option [-普通参数] 进程号 inteval count
- 比如 jstat -class [-t] 9000 1000 10
- java -XX:+PrintFlagsInitial:查看所有JVM参数启动的初始值
- java -XX:+PrintFlagsFinal:产看所有JVM参数的最终值
- java -XX:+PrintCommandLineFlags :产看被用户或者JVM设置过的详细的XX参数的名称和值
- jmap:
- -heap pid :显示堆的配置信息和使用信息。可以和jstat对比使用
- -dump 导出内存镜像文件 jmap -dump:live,format=b, filename="d:1.txt" pid # 导出存活的对象
- -histo:类的大小和对象实例的个数
- 自动方式导出 -XX:+HeapDumpOnOutMemoryError 或者 -XX:HeapDumpPath=文件名
和jstat的对比
对于死锁,jstack只可以检测到由于竞争锁而引起的死锁问题。检测由于循环等待而导致的死锁信息。
也就是说:如果两个线程永久处于blok状态,才会被检测为死锁;而永久处于wait状态是不会被检测到死锁的。
- jcmd : 可以执行stat的基本所有指令。
- jmap的替换
- jinfo的替换
- jps替换
- PrintFlagsFinal的替换
图形化的界面
2. 性能指标
注意吞吐量和延迟的区别:
- 对于web应用程序来说,吞吐量越高,延迟越低。 此处的延迟是用户体验到的延迟。
- 对于GC来说,吞吐量越高,延迟越高。
一些占用时间的过程
3. 性能分析
- 无监控,不调优;无分析,不调优。
- 监控和分析的一句
- 运行日志 : 异常堆栈的日志,以及垃圾回收日志,还有就是热点代码编译的时间,类加载时间
- 线程快照:时间上的快照
- 堆存储快照: 空间上的快照
4. 性能调优
5. 垃圾回收器选择
6. 运行时参数的设定
7. 实战案例
1.单体应用在大内存硬件上部署
- 通过单独的Java虚拟机实现管理大量的Java堆内存
- 同时使用若干个JVM,建立逻辑集群来应用硬件资源
2. 集群同步导致内存溢出
3. 堆外内存导致溢出的错误
4. 外部命令导致系统缓慢
- 由于进程调用导致的系统缓慢,处理器资源占用率很高。
- 自己的毕业设计里面 – 加载的照片很慢的原因就是存在系统调用。没法通过Django框架直接进行图片的处理,还需要进程调用。
- 问题,找不到自己电脑的Pytorch环境和tensorflow环境。
- 把下载好的tenflow的包和pytorch的包,放在项目的model里面进行引用。
- 然后调试环境就行了。
- 问题2:图片的数据库存储,否则的话会查询很慢,因为没法建立索引。应该按照小时建立索引。
- 问题3:页面的问题很大,一些功能没有实现,加上自己对前端的不熟悉,导致前端很丑,并且修改很困难。
5. 服务器虚拟机进程崩溃
-
出现了Connect Reset异常。
-
把异步调用修改成消息队列。
-
写的发送消息的那个阻塞I/O就是这样的问题。
6. 不恰当的数据结构导致内存占用过大
7. 由Windows虚拟机导致长时间停顿(存在问题)
8. 由安全点导致的长时间停顿
- 现象:
- 用户线程停顿时间特别长 2.26s,但是垃圾收集时间很短,也只有0.14s
- 使用-XX:+PrintSafepointStatisticsCount=1看到waited_to_block有两个。也就是等待两个线程,并且spin时间超过了2s。
- 解决:
- 找到最这两个线程-XX:safepointTimeoutDelay=2000
- 使用了int类型的可数循环
- 改成long类型的循环,这样每次循环就会检查安全点,不用等到跑完才会进行垃圾回收。
实战:Eclipse运行速度调优
0. 使用工具
1. 初始状态
- 启动时间15s
- GC :4.149s
- full GC 19次,3s
- Minor GC , 278次,1s
- 类加载9115个:4s
- 及时编译:2s
- 内存分布:40M新生代,472M老年代
2. 解决方案
3. 总结
- -Xverify:none
- -Xmx512m
- -Xms512m
- -Xmn128m
- -XX:PermSize=256m
- -XX:MaxPermSize=256m
- -XX:+DisableExplicitGC"
- -XX:+UseParNew
- -XX:+UseConcMarkSweepGC
- ``-XX:CMSInitialtingOccupanyFrction=85` #VMS的初始并发占内存用率为15%。
- -Xnoclassgc