堆配置:
-Xms:初始堆大小 -Xmx:最大堆大小 -Xss:规定每个线程虚拟机栈大小 -XX:NewSize=n:设置年轻代大小 -XX:NewRatio=n:设置年轻代和年老代的比值。如:为 3 表示年轻代和年老代比值为 1:3,年轻代占整个年轻代年老代和的 1/4 -XX:SurvivorRatio=n:年轻代中 Eden 区与两个 Survivor 区的比值。注意 Survivor 区有两个。如 3 表示 Eden:3 Survivor:2,一个 Survivor 区占整个年轻代的 1/5 -XX:MaxPermSize=n:设置持久代大小 -XX:MaxTenuringThreshold=n:设置经过多少次GC进入老年代 -XX:PretenureSizeThreshold=n :设置多大对象直接进入老年代,单位:byte java -XX:+PrintCommandLineFlags -version:查看虚拟机配置
收集器设置:
-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 数。并行收集线程数
打印 GC 回收的过程日志信息
-XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:filename
命令查询资源信息
top:显示系统整体资源使用情况 vmstat:监控内存和 CPU iostat:监控 IO 使用 netstat:监控网络使用 JDK 性能监控工具 jps:虚拟机进程查看 jstat:虚拟机运行时信息查看 jinfo:虚拟机配置查看 jmap:内存映像(导出) jhat:堆转储快照分析 jstack:Java 堆栈跟踪 jcmd:实现上面除了 jstat 外所有命令的功能
JDK自带可视化性能监控和故障处理工具
JConsole VisualVM Java Mission Control线上服务 CPU 占用过高怎么排查?
1)所以先需要找出那个进程占用 CPU 高。
top 列出系统各个进程的资源占用情况。
2)然后根据找到对应进行里哪个线程占用 CPU 高。
top -Hp 进程 ID 列出对应进程里面的线程占用资源情况
3)找到对应线程 ID 后,再打印出对应线程的堆栈信息
printf “%xn” PID 把线程 ID 转换为 16 进制。
jstack PID 打印出进程的所有线程信息,从打印出来的线程信息中找到上一步转换为 16 进制的线程 ID 对应的线程信息。
4)最后根据线程的堆栈信息定位到具体业务方法,从代码逻辑中找到问题所在。
查看是否有线程长时间的 watting 或 blocked,如果线程长期处于 watting 状态下, 关注 watting on xxxxxx,说明线程在等待这把锁,然后根据锁的地址找到持有锁的线程。
内存飙高问题怎么排查?分析:内存飚高如果是发生在 java 进程上,一般是因为创建了大量对象所导致,持续飚高说明垃圾回收跟不上对象创建的速度,或者内存泄露导致对象无法回收。
1)先观察垃圾回收的情况
jstat -gc PID 1000 查看 GC 次数,时间等信息,每隔一秒打印一次。
jmap -histo PID | head -20 查看堆内存占用空间最大的前 20 个对象类型,可初步查看是哪个对象占用了内存。
如果每次 GC 次数频繁,而且每次回收的内存空间也正常,那说明是因为对象创建速度快导致内存一直占用很高;如果每次回收的内存非常少,那么很可能是因为内存泄露导致内存一直无法被回收。
2)导出堆内存文件快照
jmap -dump:live,format=b,file=/home/myheapdump.hprof PID dump 堆内存信息到文件。
3)使用 visualVM 对 dump 文件进行离线分析,找到占用内存高的对象,再找到创建该对象的业务代码位置,从代码和业务场景中定位具体问题。
38.频繁 minor gc 怎么办?
优化 Minor GC 频繁问题:通常情况下,由于新生代空间较小,Eden 区很快被填满,就会导致频繁 Minor GC,因此可以通过增大新生代空间-Xmn来降低 Minor GC 的频率。
双亲委派模型的工作过程:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到最顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求时,子加载器才会尝试自己去完成加载。
为什么要用双亲委派机制?答案是为了保证应用程序的稳定有序。
例如类 java.lang.Object,它存放在 rt.jar 之中,通过双亲委派机制,保证最终都是委派给处于模型最顶端的启动类加载器进行加载,保证 Object 的一致。反之,都由各个类加载器自行去加载的话,如果用户自己也编写了一个名为 java.lang.Object 的类,并放在程序的 ClassPath 中,那系统中就会出现多个不同的 Object 类。
如何破坏双亲委派机制?如果不想打破双亲委派模型,就重写 ClassLoader 类中的 fifindClass()方法即可,无法被父类加载器加载的类最终会通过这个方法被加载。而如果想打破双亲委派模型则需要重写 loadClass()方法。



