jvm学习笔记(二)内存溢出异常

在java虚拟机规范中,除了程序计数器之外,虚拟机内存的其他几个运行时区域都有发生OutOfMemoryError(OOM)异常的可能。

1.在java虚拟机栈和本地方法栈中,如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常。如果虚拟机栈可以动态扩展,在扩展时无法申请到足够的内存则会抛出OutOfMemoryError异常。

2.Java堆在虚拟机中可以实现固定大小的也可以实现可扩展的,不过现在主流的虚拟机都按照可扩展的方式实现的,通过-Xmx(堆的最大值)和-Xms(堆的最小值)控制java堆的大小,如果在堆中没有完成实例分配,并且堆也无法在扩展时,则会抛出OutOfMemoryError异常。

3.方法区与堆类似,当方法区无法满足内存分配的需求时则会抛出OutOfMemoryError异常

4.本机直接内存的分配不会受到java堆大小的限制,但是会受到本机总内存大小以及处理器寻址空间的限制,当各个内存区域的总和大于物理内存的限制的时候,会导致动态扩展时出现OutOfMemoryError异常。

java堆的OOM一般是在实际中比较常见的异常,当出现这种异常时,异常堆栈信息是“java.lang.OutOfMemoryError”,后面跟着会提示“java heap space”。java堆出现这种异常的时候一般的解决思路是,先通过内存映像分析工具确定是内存泄漏还是内存溢出,内存泄漏指的就是某些对象是不必要的但是还有路径与GC Roots相关联导致垃圾收集器无法自动回收这些对象,我们能通过定位到内存泄漏的代码定位到具体的代码进行修改。内存溢出就是内存中的对象都是必要的,此时我们可以通过检查虚拟机的堆参数(-Xmx,-Xms)的与物理机内存对比看是否进行调整,还可以检查代码中的某些对象是否存在生命周期过长,持有状态时间过长的情况,尝试减少程序运行期间的内存消耗。

虚拟机栈和本地方法栈可以通过-Xss参数设置栈的大小,一般在单线程的情况下,常出现的是StackOverflowError异常,这种异常可以通过错误堆栈的信息很好修复异常,但是在多线程的情况下,很容易导致OutOfMemoryError异常,这种内存溢出解决的方法是减少线程数或者更换64位虚拟机,或者减少最大堆和减少栈容量来换取更多的线程。

本机直接内存溢出,这种异常的明显特征是Heap Dump文件中不会看到明显的异常,如果dump文件很小而程序中又直接或者间接使用了NIO,那么就有可能是本机直接内存溢出。可通过-XX指定直接内存的大小。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值