[转载] java中关于OOM的场景及解决方法

1、OOM for Heap=>例如:java.lang.OutOfMemoryError: Java heapspace
【分析】
 此OOM是由于JVM中heap的最大值不满足需要,将设置heap的最大值调高即可,参数样例为:-Xmx2G
【解决方法】
调高heap的最大值,即-Xmx的值调大。

2、OOM for Perm=>例如:java.lang.OutOfMemoryError: Java permspace
【分析】
 此OOM是由于JVM中perm的最大值不满足需要,将设置perm的最大值调高即可,参数样例为:-XX:MaxPermSize=512M
【解决方法】
调高heap的最大值,即-XX:MaxPermSize的值调大。
另外,注意一点,Perm一般是在JVM启动时加载类进来,如果是JVM运行较长一段时间而不是刚启动后溢出的话,
很有可能是由于运行时有类被动态加载进来,此时建议用CMS策略中的类卸载配置。
如:-XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled

3、OOM for GC=>例如:java.lang.OutOfMemoryError: GC overheadlimit exceeded
【分析】
此OOM是由于JVM在GC时,对象过多,导致内存溢出,建议调整GC的策略,在一定比例下开始GC而不要使用默认的策略,或者将新代和老代设置合适的大小,
需要进行微调存活率。
【解决方法】
改变GC策略,在老代80%时就是开始GC,并且将-XX:SurvivorRatio(-XX:SurvivorRatio=8)和-XX:NewRatio(-XX:NewRatio=4)设置的更合理。

4、OOM for native thread created=>例如:java.lang.OutOfMemoryError: unable tocreate new native thread
【分析】
参考如下:
(MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Numberof threads 
MaxProcessMemory   指的是一个进程的最大内存
JVMMemory         JVM内存
ReservedOsMemory   保留的操作系统内存
ThreadStackSize      线程栈的大小
如果JVM内存调的过大或者可利用率小于20%,可以建议将heap及perm的最大值下调,并将线程栈调小,即-Xss调小,如:-Xss128k
【解决方法】
在JVM内存不能调小的前提下,将-Xss设置较小,如:-Xss:128k

5、OOM for allocate huge array=>例如:Exception in thread "main":java.lang.OutOfMemoryError: Requested array size exceeds VM limit 
【分析】
此类信息表明应用程序(或者被应用程序调用的APIs)试图分配一个大于堆大小的数组。例如,如果应用程序new一个数组对象,大小为512M,但是最大堆大小为256M,因此OutOfMemoryError会抛出,因为数组的大小超过虚拟机的限制。
【解决方法】
(1)、首先检查heap的-Xmx是不是设置的过小
(2)、如果heap的-Xmx已经足够大,那么请检查应用程序是不是存在bug,例如:应用程序可能在计算数组的大小时,存在算法错误,导致数组的size很大,从而导致巨大的数组被分配。

6、 OOM for small swap=>例如:Exception in thread "main": java.lang.OutOfMemoryError:request <size> bytes for <reason>. Out of swap space? 
 【分析】
 抛出这类错误,是由于从native堆中分配内存失败,并且堆内存可能接近耗尽。这类错误可能跟应用程序没有关系,例如下面两种原因也会导致错误的发生:
(1)操作系统配置了较小的交换区
(2)系统的另外一个进程正在消耗所有的内存
 【解决方法】
(1)、检查os的swap是不是没有设置或者设置的过小
(2)、检查是否有其他进程在消耗大量的内存,从而导致当前的JVM内存不够分配。

注意:虽然有时<reason>部分显示导致OOM的原因,但大多数情况下,<reason>显示的是提示分配失败的源模块的名称,所以有必要查看日志文件,如crash时的hs文件。

时间: 2024-08-07 16:33:05

[转载] java中关于OOM的场景及解决方法的相关文章

Java中关于OOM的场景及解决方法

原文地址:http://developer.51cto.com/art/201112/305696.htm 1.OOM for Heap=>例如:java.lang.OutOfMemoryError: Java heap space分  析:此OOM是由于JVM中heap的最大值不满足需要,将设置heap的最大值调高即可,参数样例为:-Xmx2G解决方法:调高heap的最大值,即-Xmx的值调大.2.OOM for Perm=>例如:java.lang.OutOfMemoryError: Ja

iOS中常见的 Crash 场景以及解决方法

1. 常见的 Crash 场景 访问了僵尸对象 访问了不存在的方法 数组越界 在定时器下一次回调前将定时器释放,会Crash 2.  关于BAD_ACCESS  出现的原因: 访问了野指针, 比如访问已经释放对象的成员变量或者发消息, 死循环等; 解决方法: 1.  重写对象的respondsToSelector 方法, 先找到出现 EXECBADACCESS 前访问的最后一个 object; 2. 设置Enable Zombie Objects; 3. 设置全局断点快速定位问题代码所在行,接收

[转载]Java中异常的捕获顺序(多个catch)

http://blog.sina.com.cn/s/blog_6b022bc60101cdbv.html [转载]Java中异常的捕获顺序(多个catch) (2012-11-05 09:47:28) 转载▼ 标签: 转载 分类: 转载 原文地址:Java中异常的捕获顺序(多个catch)作者:leesa Java代码 import java.io.IOException; public class ExceptionTryCatchTest { public void doSomething(

java中如何实现一个优美的equals方法

java中的任何类都从老祖宗Object中集成了equals方法,在编程实践中应用使用equals方法判断两个对象是否相同的场景无处不在,所以我们在实现自己的类是必须重写出一个优美的equals方法. 首先让我们来看看java语言规范中对equals方法的说明,一个equals方法应当满足如下几个特性: 自反性,对任何一个非空的引用x,x.equals(x)必须返回true: 对称性,对任何引用x和y来说,如果x.equals(y)返回true,那么y.equals(x)也必须返回true: 传

java中的List记录是否完全匹配方法

今天要说的是给List分组,然后用Map来封装,可能你看了以后还是有一些模糊. 先看一下项目结构图: User类是一个VO类,主要逻辑还是在MapTestBak上面. 运行效果: 原理图: 1.在starsList中有两组人,共三人 2.在dolList中有一组人,共两人 3.经过marched操作,最后匹配到一组人到result中.即第一组人. 原理很简单. =================================================== 源码部分: ==========

Java中获取键盘输入值的三种方法

Java中获取键盘输入值的三种方法     Java程序开发过程中,需要从键盘获取输入值是常有的事,但Java它偏偏就没有像c语言给我们提供的scanf(),C++给我们提供的cin()获取键盘输入值的现成函数!Java没有提供这样的函数也不代表遇到这种情况我们就束手无策,请你看以下三种解决方法吧: 以下将列出几种方法: 方法一:从控制台接收一个字符,然后将其打印出来 import java.io.*; public static void main(String [] args) throws

Struts2中使用execAndWait后,在 Action中调用getXXX()方法报告java.lang.NullPointerException异常的原因和解决方法

使用 Struts2 编写页面,遇到一个要长时间运行的接口,因此增加了一个execAndWait ,结果在 Action 中调用 getContext()的时候报告异常 1 ActionContext context = ActionContext.getContext(); 2 ServletContext servletContext = (ServletContext) context.get(ServletActionContext.SERVLET_CONTEXT); //抛空指针异常

java小知识点(一)---Java中获取键盘输入值的三种方法

Java中获取键盘输入值的三种方法   程序开发过程中,需要从键盘获取输入值是常有的事,但Java它偏偏就没有像c语言给我们提供的scanf(),C++给我们提供的cin()获取键盘输入值的现成函数!Java没有提供这样的函数也不代表遇到这种情况我们就束手无策,请你看以下三种解决方法吧:   以下将列出几种方法:   方法一:从控制台接收一个字符,然后将其打印出来   publicstatic void main(String [] args) throws IOException{   Sys

java中判断字符串是否为数字的方法的几种方法

Java中判断字符串是否为数字的方法: 1.用JAVA自带的函数 public static boolean isNumeric(String str){ for (int i = 0; i < str.length(); i++){ System.out.println(str.charAt(i)); if (!Character.isDigit(str.charAt(i))){ return false; } } return true; } 2.用正则表达式 首先要import java.