OOM是什么?笔记

OOM(Out Of Menmory Error)

JAVA虚拟机中 除程序计数器意外 虚拟机的内存其他几个运行时区域都有发生OOM的可能

Java 堆溢出

GC Roots 到对象之间有可达路径来避免垃圾回收机智清理这些对象 就会在对象数量达到最大堆的绒容量 然后产生内存溢出异常
Eclipse 的 Debug 页面中设置虚拟机参数
代码:
-verbose:gc -Xms20M -Xmx20M Xmn10M -XX:+PrintGCDaetails -XX:SurvivorRatio=8
JAVA堆的大小设置最小值 -Xms 
JAVA堆的大小设置最大值 -Xmx

解决异常

首先通过内存映射分析工具 如 Eclipse Memory Analyzer 堆 dump出的异常堆转储进行快照解析确认内存中的对象是否是必要的  也就是先分清楚是 内存泄漏 Memory Leak 还是Memory Overflow 如果是内存泄漏 可通过工具进一步查看泄露的对象到GC Roots的引用链 就能找到泄露对象是怎么通过路径与 GC Roots 相关联导致垃圾收集器无法回收他们如果不存在泄露 就检查堆参数 -Xmx 与 -Xms 与机器物理内存对比是否还可以调大 从代码上检测 是否是某些对象的生命周期过长持有状态时间过长 尝试减少代码运行期间的内存消耗


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

HotSpot 虚拟机不区分 虚拟机栈 和 本地方法栈 因此Xoss(设置本地方法栈内存大小)参数虽然存在但是是无效的
虚拟机栈 和 本地方法栈两种异常:
线程请求栈的深度大于虚拟机允许的最大深度 抛出 StackOverflowError

如果虚拟机在扩展栈是无法申请到足够的内存空间 抛出 Out Of Menmory Error

注:单个线程下 无论是栈帧太大还是虚拟机栈容量太小当内存无法分配的时候抛出的都是StackOverflowError


运行时常量池溢出

如果向运行时常亮去添加内容最简单的做法就是使用 String.intern() 这个 Narive 方法 该方法作用是如果池中包含一个等于此String对象的字符串 则返回代表池中这个字符串的 String 对象 否则将该 String 对象 的字符串添加到常量池中并返回此 String 对象的引用-XX:PermSize 方法区最小 -XX:MaxPermSize 方法区最大值如果运行时常量池 OOM 提示信息为 OutOfMemoryError : PermGen space 表示运行时常量池属于方法区的一部分 


方法区溢出

方法区是用于存放 Class信息的 如类名 访问修饰符 常量池 等当前主流AOP框架 (Spring Hibernate 等) 都会使用到 CFLib 这类字节码技术对类进行加强 增强的类越多 就越需要越大的方法区来保证 动态生成的Class 可以载入内存在动态生成大量 Class 的应用中 需要特别注意类的回收状况  注:除了使用GCLib字节码增强意外 常见的还有 JSP 或者动态产生JSP的应用文件(JSP在第一次运行时要编译为JAVA类)或是基于 OSGi(注:  OSGi(Open Service Gateway Initiative)技术是Java动态化模块化系统的一系列规范。OSGi一方面指维护OSGi规范的OSGI官方联盟,另一方面指的是该组织维护的基于Java语言的服务(业务)规范。简单来说,OSGi可以认为是Java平台的模块层。) 的应用即使是同一个类呗不同的加载器加载也会视为不同的类



本机直接内存溢出

DirectMemory 可通过-XX:MaxDirectMemorySize 指定 如果不指定则和JAVA堆的最大值一样使用DirectByteBuffer分配内存也会抛出内存溢出异常 但是他抛出异常的时候并没有向计算机申请分配内存 而是通过计算机内存得知是否可以分配于是抛出异常申请分配内存的方法是unsafe.allocateMemory();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值