目录

  • 前言
  • JVM性能调优
    • 内存溢出错误
      • 堆溢出错误和预判堆溢出的错误
      • 虚拟机栈和本地方法栈溢出错误
      • 方法区(元数据区)和运行时常量池溢出
      • 直接内存区域的溢出
    • 实践案例
      • 如何正确利用大内存-高性能硬件上的程序部署策略
      • 如何排查内存溢出错误
      • 如何排查系统CPU性能指标异常-外部命令导致系统缓慢

返回目录

前言

JVM性能调优是一个很大的话题,很多中小企业的业务规模受限,没有迫切的性能调优需求,但是如果不知道JVM相关的理论知识,写出来的代码或者配置的JVM参数不合理时,就会出现很严重的性能问题,到时候开发就会像热锅上的蚂蚁,等待各方的炙烤。笔者一直在学习JVM相关的理论书籍,看过周志明老师的 深入理解Java虚拟机,也学习过 葛鸣老师的 实战Java虚拟机 ,但是在实际工作中,只有过寥寥几次的调优经验,几乎无处施展学习到的理论知识,致使知识大部分都存在在笔记和书本中,这次总结面试题,一是希望能够应对性能调优岗位相关的面试;二是希望总结一下具体的实战步骤,并努力吸收书中的实践案例,让自己的经验更丰富一些。

返回目录

JVM性能调优

返回目录

内存溢出错误

学习目的:

  • 通过异常信息及时定位到发生内存溢出的运行时数据区域
  • 了解什么样的代码会导致内存溢出,防止写出这样的代码
  • 出现异常后该如何处理,也就是学习事中的处理手段

内存溢出和内存泄露的区别

  • 内存泄露:不该留存在进程中的内存数据,虽然很小,但是在经过多次长期的积累后,会导致内存溢出
  • 内存溢出:程序申请内存时,内存不足的现象

返回目录

堆溢出错误和预判堆溢出的错误

如何复现出堆溢出错误?

  • JVM参数部分:最大堆和最小堆设置相同并且设置的比较小,比如只有10M,这样就不会自动扩展堆
  • 代码部分:在一个方法中不断地往集合中加入元素

代码实践

package org.example;import java.util.ArrayList;import java.util.List;/** * -Xmx10M -Xms10M -XX:+HeapDumpOnOutOfMemoryError */public class App {static class OOMObject {int a = 1;long b = 2;float c = 2.1f;}public static void main(String[] args) {List list = new ArrayList();while (true) {list.add(new OOMObject());}}}

正确的出现了我们想要的结果:

java.lang.OutOfMemoryError: Java heap spaceDumping heap to java_pid24476.hprof ...Heap dump file created [13268403 bytes in 0.077 secs]Exception in thread "main" java.lang.OutOfMemoryError: Java heap spaceat java.util.Arrays.copyOf(Arrays.java:3210)at java.util.Arrays.copyOf(Arrays.java:3181)at java.util.ArrayList.grow(ArrayList.java:265)at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:239)at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:231)at java.util.ArrayList.add(ArrayList.java:462)at org.example.App.main(App.java:22)Process finished with exit code 1

如果把参数调大,调整20M,那么会报另外的error

java.lang.OutOfMemoryError: GC overhead limit exceededDumping heap to java_pid8796.hprof ...Heap dump file created [27391983 bytes in 0.141 secs]Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceededat org.example.App.main(App.java:19)Process finished with exit code 1

这个错误的原因是,JVMGC时间占据了整个运行时间的98%,但是回收只得到了2%可用的内存,至少出现5次,就会报这个异常。