一文带你搞懂JVM 调优

目录

1、内存泄漏与内存溢出

1、内存泄漏

2、内存溢出

2、提高垃圾回收效率的方法

3、常用的命令

4、常用的JVM参数

1、设置堆内存大小

2、设置新生代内存大小

3、设置元空间内存大小

扫描二维码关注公众号,回复: 16728454 查看本文章

4、设置使用哪种垃圾回收器

5、记录垃圾回收日志


1、内存泄漏与内存溢出

内存泄漏与内存溢出的区别:

  • 内存泄漏:不再被使用的对象占用的内存空间,本应该被释放,但没有被垃圾回收掉。
  • 内存溢出:在程序运行中,无法申请到足够的内存资源。

1、内存泄漏

产生原因:

  • 使用静态的集合类。静态变量不会被垃圾回收,而集合占用的内存又一般很大。
  • 各种连接没有及时关闭,比如数据库连接、IO连接
  • 一些强引用的对象,在不使用后没有置为null,导致无法被回收
  • 变量的作用域设置不合理,存活周期过长
  • 过多的单例模式类

解决方案:

  • 避免在循环中创建对象,尽量复用对象
  • 及时释放无用的对象引用
  • 少用静态集合
  • 及时关闭连接
  • 对于String的操作,使用StringBuilder或者StringBuffer,不要直接拼接字符串

2、内存溢出

内存溢出的情况:

  • 虚拟机栈和本地方法栈溢出
    • 如果线程请求的栈深度,大于虚拟机允许的栈深度,抛出StackOverflowError
    • 如果虚拟机在扩展栈时,无法申请到足够的内存空间,抛出OutOfMemoryError
  • 堆溢出
    • 遇到堆溢出,必须先判断,到底是发生了内存泄漏还是内存溢出
    • 如果是内存泄漏,通过工具查看泄漏对象到 GC Roots 的引用链,找到泄漏对象无法被垃圾收集器自动回收的原因。
    • 如果不是内存泄漏,而且代码看不出问题,就考虑增大虚拟机的内存参数(-Xmx 与-Xms)
  • 方法区溢出
    • 考虑修改方法区占用的内存大小
  • 运行时常量池溢出

内存溢出的原因:

  • 内存中加载的数据过于庞大
  • 代码中存在死循环,或者存在大量对象的创建
  • 虚拟机内存参数设置过小

内存溢出的解决方案:

  • 修改JVM内存参数。一般将-Xms 和-Xmx 设置成相同的值,避免每次GC后调整堆的大小。堆一般设置为物理内存的80%
  • 检查错误日志,查看内存溢出背后的实际原因
  • 对代码进行走查和分析,排查产生错误的代码
  • 使用内存查看工具,动态地监视内存的使用情况,尝试复现内存溢出的场景,进而发现问题。

2、提高垃圾回收效率的方法

  • 对象不再使用时,及时将它显式置为null,方便垃圾收集器快速判断
  • 少用 System.gc(),因为它会触发Full GC
  • 少用静态变量。静态变量会作为GC Roots,永远不会回收。
  • 对于String的操作,使用StringBuilder或者StringBuffer,不要直接拼接字符串。因为会在堆上产生很多额外的字符串对象
  • 分散对象创建和销毁的时机,不要突然创建或销毁大量对象,因为这样可能会触发Full GC
  • 少用finalize()方法,会加重垃圾回收的负担
  • 善用弱引用与软引用类型,不要全部使用强引用
  • 能用基本数据类型,就不要使用包装类型。因为包装类型占用了更大的内存
  • 增大堆内存,可以减少垃圾回收的频率。

3、常用的命令

4、常用的JVM参数

1、设置堆内存大小

-Xms<heap size>[unit] 
-Xmx<heap size>[unit]
  • heap size:内存大小
  • unit:单位,比如k、m、g

比如要设置最小为2G,最大为5G:

-Xms2g -Xmx5g

2、设置新生代内存大小

默认新生代的内存是1G左右,最大无上限

有两种设置新生代内存大小的方式:

指定最小值和最大值

-XX:NewSize=<young size>[unit] 
-XX:MaxNewSize=<young size>[unit]

规定新生代内存为一个固定值

-Xmn256m 

设置新生代与老年代的比值

-XX:NewRatio=1
  • 含义是,整个新生代(包括Eden、From Survivor、To Survivor)和老年代的内存占比

3、设置元空间内存大小

由于元空间是在直接内存上的,而直接内存对应着宿主机物理内存。

所以如果不对元空间的大小做限制,随着运行创建了大量的类,有可能会耗尽宿主机的所有内存。

设置元空间的最小值和最大值

-XX:MetaspaceSize=N
-XX:MaxMetaspaceSize=N

4、设置使用哪种垃圾回收器

-XX:+UseSerialGC
-XX:+UseParallelGC
-XX:+UseParNewGC
-XX:+UseG1GC

5、记录垃圾回收日志

-XX:+UseGCLogFileRotation 
-XX:NumberOfGCLogFiles=< number of log files > 
-XX:GCLogFileSize=< file size >[ unit ]
-Xloggc:/path/to/gc.log

猜你喜欢

转载自blog.csdn.net/m0_62609939/article/details/131919548