OutOfMemoryError简单来讲就是JVM没有内存可用啦,具体来讲就是分配的heap空间不能再往里面放新的对象了.
通常来讲造成这种错误的原因主要有:
1,达到了heap所能支持的最大值.
heap空间太小,放不下要new的对象,举一个极端的例子,heap的size是64m,你要new的对象占用的size
为65m.比如业务高峰期发生,加载大的XML dom对象等.
2,"内存泄漏",heap中积累垃圾回收器不能回收的大量对象.
JVM的垃圾回收器会自动回收那些没有任何变量引用的对象,但是如果一个对象已经不使用了,但是还有
变量引用它(由于代码逻辑的错误),比如自己实现的一个缓存(map),对象不断的加进去,没有使用合适的
策略从缓存中清理.
JDK6之后,JAVA提供了很多工具来帮助发现上面的问题.
1,jps:查看有哪些java进程正在运行.
2,jmap -dump:file=heap_file_name pid 将某一个java进程的JVM信息dump出来.
如jmap -dump:file=Test1JVM 412,进程412的JVM信息会dump为文件Test1JVM.
3,jhat分析dump的文件,如jhat Test1JVM,然后打开浏览器http://localhost:7000/ 浏览.
4,>jconsole,可以实时观察JVM的运行信息.
5,java运行是指定参数 -XX:+HeapDumpOnOutOfMemoryError在发生OutOfMemoryError的时候将JVM
的信息dump成文件.
下面通过一个例子来观察:
Java代码如下:不断的创建一个对象,并将它放在一个list里面然JVM垃圾回收器不能回收.
java -Xms32M -Xmx32M -XX:+HeapDumpOnOutOfMemoryError -cp t1.jar com.test.Test1
通过jconsole观察到的内存使用情况如下图:
java运行的控制台打印如下信息:
C:\Program Files\Java\jdk1.6.0_3\bin>jhat d:\temp\java_pid5436.hprof
从http://localhost:7000/访问jhat的分析结果
主要看Show instance counts for all classes (excluding platform)
这时候可以看到这时候JVM中有些什么样的对象,对象的个数.
通过查看References to this object:
可以发现引用class com.test.TObject的为:
References to this object:
java.util.ArrayList@0x24df9c00 (20 bytes) : field elementData
可以发现引用java.util.ArrayList@0x24df9c00的为:
References to this object:
com.test.Test1@0x24df6638 (12 bytes) : field list
这样就可以分析OutOfMemoryError的原因了.
通常来讲造成这种错误的原因主要有:
1,达到了heap所能支持的最大值.
heap空间太小,放不下要new的对象,举一个极端的例子,heap的size是64m,你要new的对象占用的size
为65m.比如业务高峰期发生,加载大的XML dom对象等.
2,"内存泄漏",heap中积累垃圾回收器不能回收的大量对象.
JVM的垃圾回收器会自动回收那些没有任何变量引用的对象,但是如果一个对象已经不使用了,但是还有
变量引用它(由于代码逻辑的错误),比如自己实现的一个缓存(map),对象不断的加进去,没有使用合适的
策略从缓存中清理.
JDK6之后,JAVA提供了很多工具来帮助发现上面的问题.
1,jps:查看有哪些java进程正在运行.
D:\temp>jps
412 Test1
5716 Main
4724
2476 JConsole
2072 Jps
412 Test1是通过 java -cp t1.jar com.test.Test1 命令启动的一个java进程.
2,jmap -dump:file=heap_file_name pid 将某一个java进程的JVM信息dump出来.
如jmap -dump:file=Test1JVM 412,进程412的JVM信息会dump为文件Test1JVM.
3,jhat分析dump的文件,如jhat Test1JVM,然后打开浏览器http://localhost:7000/ 浏览.
4,>jconsole,可以实时观察JVM的运行信息.
5,java运行是指定参数 -XX:+HeapDumpOnOutOfMemoryError在发生OutOfMemoryError的时候将JVM
的信息dump成文件.
下面通过一个例子来观察:
Java代码如下:不断的创建一个对象,并将它放在一个list里面然JVM垃圾回收器不能回收.
public class TObject {
int[] arr = new int[20000];
}
public class Test1 {
private List<TObject> list = new ArrayList<TObject>();
public void test(){
int i=0;
while(true){
try {
Thread.sleep(100);
list.add(new TObject());
i++;
System.out.println("There are " + i + " objects created");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] aregs){
new Test1().test();
}
}
运行上面这个java类Test1,指定heap的大小为32m,在OutOfMemoryError的时候dump jvm信息.
java -Xms32M -Xmx32M -XX:+HeapDumpOnOutOfMemoryError -cp t1.jar com.test.Test1
通过jconsole观察到的内存使用情况如下图:
java运行的控制台打印如下信息:
.....
There are 407 objects created
There are 408 objects created
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid5436.hprof ...
Heap dump file created [35684233 bytes in 1.525 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.test.TObject.<init>(TObject.java:28)
at com.test.Test1.test(Test1.java:38)
at com.test.Test1.main(Test1.java:47)
运行jhat:
C:\Program Files\Java\jdk1.6.0_3\bin>jhat d:\temp\java_pid5436.hprof
从http://localhost:7000/访问jhat的分析结果
主要看Show instance counts for all classes (excluding platform)
这时候可以看到这时候JVM中有些什么样的对象,对象的个数.
通过查看References to this object:
可以发现引用class com.test.TObject的为:
References to this object:
java.util.ArrayList@0x24df9c00 (20 bytes) : field elementData
可以发现引用java.util.ArrayList@0x24df9c00的为:
References to this object:
com.test.Test1@0x24df6638 (12 bytes) : field list
这样就可以分析OutOfMemoryError的原因了.