java OOM 分析汇总

哪些地方会有OOM

jvm内存模型

线程私有

程序计数器:当前线程执行的字节码指示器

虚拟机栈:java方法执行的内存模型,每个方法的执行,就是栈帧进栈和出栈的操作过程

本地方法栈:native方法的运行提供内存环境

线程共享

方法区:用于存储jvm的类加载信息、常量、静态变量,即时编译器编译后的代码等,又称永久代

常量池:常量信息如:符号引用、字面量

堆:对象内存分配的地方,垃圾回收的主要区域

直接内存:并不是JVM运行时数据区的一部分, 可直接访问的内存,

除了程序计数器,其他地方都有可能OOM

为什么会有OOM

原因

内存分配少了:虚拟机本身分配的内存太小了

内存溢出:申请的内存超出了jvm总内存的大小

应用用的多了:应用用的内存多了,并且没有释放

内存泄漏:申请使用完后没有释放,导致虚拟机不能再次使用

OOM类型

java.lang.OutOfMemoryError: Java heap space

堆内存分配少了:-Xms -Xmx

使用不当:通过监控软件查找

java.lang.OutOfMemoryError: PermGen space

大量class或jsp页面,类的信息会存在这个里面:-XX:PermSize -XX:MaxPermSize

大量CGLIB反射动态代理,大量类的信息

过量常量和字符串

java.lang.StackOverflowError

程序中存在死循环

栈内存设置太小:-Xss

如何定位OOM

设置参数:-XX:+HeapDumpOnOutOfMemoryError 设定当发生OOM时自动dump出堆信息

dump命令工具

jps:定位进程PID

jmap:jmap -dump:format=b,file=heap.bin PID

jmap -dump:live,file=a.log pid

工具

jconsole

jvisovm

分析工具

jhat

jhat -J-Xmx512M a1.log

http://localhost:7000

(1)查询长度大于100的字符串

select s from java.lang.String s where s.count > 100

(2)查询长度大于256的数组

select a from [I a where a.length > 256

(3)显示匹配某一正则表达式的字符串

select a.value.toString() from java.lang.String s where /java/(s.value.toString())

(4)显示所有文件对象的文件路径

select file.path.value.toString() from java.io.File file

(5)显示所有ClassLoader的类名

select classof(cl).name from instanceof java.lang.ClassLoader cl

(6)通过引用查询对象

select o from instanceof 0xd404d404 o

mat

如何预防OOM

增加jvm内存

配置XX:+HeapDumpOnOutOfMemoryError

防止死循环

定位问题

防止动态代理加载类过多

防止内存使用不释放

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容