OOM异常与jvm参数调优

一.OOM存在的几种情况.

除了程序计数器外,虚拟机内存的其他几个运行时区域都可能发OOM.只不过堆内存溢出最为常见.

1, 堆内存溢出


一般的异常信息:java.lang.OutOfMemoryError:Java heap spacess

   java堆用于存储对象实例,我们只要不断的创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,就会在对象数量达到最大堆容量限制后产生内存溢出异常。

2, 虚拟机栈和本地方法栈溢出

   如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。

   如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常

   这里需要注意当栈的大小越大可分配的线程数就越少。

3, 运行时常量池溢出

异常信息:java.lang.OutOfMemoryError:PermGen space
如果要向运行时常量池中添加内容,最简单的做法就是使用String.intern()这个Native方法。该方法的作用是:如果池中已经包含一个等于此String的字符串,则返回代表池中这个字符串的String对象;否则,将此String对象包含的字符串添加到常量池中,并且返回此String对象的引用。由于常量池分配在方法区内,我们可以通过
-XX:PermSize和-XX:MaxPermSize
限制方法区的大小,从而间接限制其中常量池的容量。

4, 方法区溢出

异常信息:java.lang.OutOfMemoryError:PermGen space

   方法区用于存放Class的相关信息,如类名、访问修饰符、常量池、字段描述、方法描述等。

   方法区溢出也是一种常见的内存溢出异常,一个类如果要被垃圾收集器回收,判定条件是很苛刻的。在经常动态生成大量Class的应用中,要特别注意这点。

二.几种问题的常见排查思路

1.堆内存溢出检查.

(1).在程序启动时我们可以设置以下参数以便在内存溢出时生成dump文件:
   -XX:Xms20m;
    -XX:Xms20m:
    -XX:+HeapDumpOnOutOfMemoryError
    -XX:HeapDumpPath=D:/(注意这里没有加号)

以上的命令是已经发生内存溢出的时候我们配置让其输出溢出信息.在实际工作中不可能等到真正溢出再去处理,会实时监控数据.

(2).使用jmap实时查看内存情况/导出dump文件
一般来说有以下几步:
    (1).jps -l:找到当前进程id.
    (2).jmap -heap pid:查看当前进程的数据.(老年代新生代的使用情况)
    (3).jmap -dump:format=b,file=app.hprof pid(导出该进程的hprof的文件,关于内存情况的映射)
说明:file后面跟的是文件名称,文件路径自动生成,显示在cmd中,去对应路径中找文件即可.

2.Java进程CPU占用过高检查.

在这里插入图片描述

3.Java进程内存泄漏.

主要使用 jstat 命令查看GC情况.
jstat -gc pid [interval]

各个参数意义如下:
在这里插入图片描述

三.JVM调优

传送门:面试官:如何进行 JVM 调优(附真实案例)

   jvm 调优,调的是稳定,并不能带给你性能的大幅提升。服务稳定的重要性就不用多说了,保证服务的稳定,gc 永远会是 Java 程序员需要考虑的不稳定因素之一。复杂和高并发下的服务,必须保证每次 gc 不会出现性能下降,各种性能指标不会出现波动,gc 回收规律而且干净,找到合适的 jvm 设置。Full gc 最会影响性能,根据代码问题,避免 full gc 频率。可以适当调大年轻代容量,让大对象可以在年轻代触发 yong gc,调整大对象在年轻代的回收频次,尽可能保证大对象在年轻代回收,减小老年代缩短回收时间.

1.几个常用工具.

2.命令示例.

3.调优-设置新生代和老年代内存比例.

1.这个参数对系统性能以及GC行为有很大影响,

新生代一般设置整个堆空间的1/3-1/4.
    -Xmn10m: 设置新生代初始大小为10m.

2.-XX:SurvivorRatio:用来设置新生代中eden空间和from/to空间的比例.
    也就是-XX:SurvivorRatio=eden/from=eden/to
    举例:-Xmn10m -XX:SurvivorRatio=2 那么eden5m,from和t各2.5m
3.-XX:NewRatio=老年代/新生代
    设置老年代和新生代比例.

基本策略:

尽可能将对象预留在新生代,减少老年代的GC次数.

补充:
oracle并没有将所有的堆参数形成一个文档,如果我们想查阅某个参数的话,可以通过命令查看.
java -XX:+PrintFlagsFinal -version

在这里插入图片描述

如果需要查哪方面的参数,直接在后面grep即可.

本文转载自:分析解决OOM与JVM参数调优

猜你喜欢

转载自blog.csdn.net/qq_36256590/article/details/132446928
今日推荐