优化从几个方面思考:1. i/o 2. cpu 3. 内存 4. 锁 5. GC情况
问题诊断:
-IO、CPU瓶颈定位:
- 使用top命令,大致查看系统cpu和内存等资源的使用情况。
- 通过jps命令查看java进程,可以查看启动命令及参数。
jps -m(查看传递给main函数的参数)-l(输出主函数的路径)-v(查看虚拟机参数) - 找出进程pid,然后使用pidstat查看线程对cpu、io、内存的使用情况。
- 使用jstack查看进程中所有线程的具体执行情况。根据pidstat的结果查看具体线程的执行情况。
-GC问题
- 使用jstat -gc查看程序GC大致情况(优化一般减少gullGC次数,主要应对的是老年代回收率太高,导致原因是大量对象没有到达存活年限直接进入老年代引起的,优化方法一般是增大新生代内存容量)
-锁信息
- jstack -l 1218
-其他工具
- jinfo查看虚拟机参数。
- jmap生成java程序的堆文件dump.txt。
- 使用jhat分析dump后的文件。可以查看所有的类信息、类的实例数量、以及实例的具体信息。(定位是否有大量垃圾没有回收,定位程序是否可以优化减少垃圾的产生)
-分析java堆:
-找到内存溢出的原因:
- 堆溢出:
原因:一般是大量大量内存分配在堆上,导致堆的大小超出-Xmx参数设置的最大堆内存,导致堆溢出。
方法:1. 增加对资源 2. 使用MAT工具分析找到大量占用对内存的对象,并在应用程序上进行合理的优化。 - 直接内存溢出:
原因:直接内存不一定能触发垃圾回收,只有直接内存达到参数-XX:MaxDirectMemorySize所指定的容量时,才会触发垃圾回收。此参数的默认大小为-Xmx最大对内存所指定的容量。
方法:1. 设置一个系统可达的-XX:MaxDirectMemorySize容量。2. 可以执行显示GC,触发垃圾回收。(说明GC可以回收直接内存)。 - 过多线程导致OOM
原因:内存不足,线程数过多导致内存溢出。
方法:1. 减少对内存,增大栈可用内存。2. 减少每一个线程所占用的内存空间,使用 -Xss参数。3. 减少线程数。 - 元数据区(永久区)溢出
原因:元数据区加载了很多的类(使用cglib动态代理可以产生新类)