优化从几个方面思考:1. i/o 2. cpu 3. 内存 4. 锁 5. GC情况
问题诊断:
-IO、CPU瓶颈定位:

  1. 使用top命令,大致查看系统cpu和内存等资源的使用情况。
  2. 通过jps命令查看java进程,可以查看启动命令及参数。
    jps -m(查看传递给main函数的参数)-l(输出主函数的路径)-v(查看虚拟机参数)
  3. 找出进程pid,然后使用pidstat查看线程对cpu、io、内存的使用情况。
  4. 使用jstack查看进程中所有线程的具体执行情况。根据pidstat的结果查看具体线程的执行情况。

-GC问题

  1. 使用jstat -gc查看程序GC大致情况(优化一般减少gullGC次数,主要应对的是老年代回收率太高,导致原因是大量对象没有到达存活年限直接进入老年代引起的,优化方法一般是增大新生代内存容量)

-锁信息

  1. jstack -l 1218

-其他工具

  1. jinfo查看虚拟机参数。
  2. jmap生成java程序的堆文件dump.txt。
  3. 使用jhat分析dump后的文件。可以查看所有的类信息、类的实例数量、以及实例的具体信息。(定位是否有大量垃圾没有回收,定位程序是否可以优化减少垃圾的产生)

-分析java堆:
-找到内存溢出的原因:

  1. 堆溢出:
    原因:一般是大量大量内存分配在堆上,导致堆的大小超出-Xmx参数设置的最大堆内存,导致堆溢出。
    方法:1. 增加对资源 2. 使用MAT工具分析找到大量占用对内存的对象,并在应用程序上进行合理的优化。
  2. 直接内存溢出:
    原因:直接内存不一定能触发垃圾回收,只有直接内存达到参数-XX:MaxDirectMemorySize所指定的容量时,才会触发垃圾回收。此参数的默认大小为-Xmx最大对内存所指定的容量。
    方法:1. 设置一个系统可达的-XX:MaxDirectMemorySize容量。2. 可以执行显示GC,触发垃圾回收。(说明GC可以回收直接内存)。
  3. 过多线程导致OOM
    原因:内存不足,线程数过多导致内存溢出。
    方法:1. 减少对内存,增大栈可用内存。2. 减少每一个线程所占用的内存空间,使用 -Xss参数。3. 减少线程数。
  4. 元数据区(永久区)溢出
    原因:元数据区加载了很多的类(使用cglib动态代理可以产生新类)