看到OOM的很多文章,然后自己也测试了下。每段程序都写了OOM的原因。从java内存模型开始分析就行了。
估计也不是太难。就是用jconsole监控资源的时候,感觉不太舒服。
package com.oom;
import java.util.ArrayList;
import java.util.List;
/*
* 堆oom
* 类的实例放到heap中,所以不断创建类就可以测试出heap的oom了
* jconsole可以监控资源
*
* Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
*/
public class HeapOOM {
static class TestHeepObject{
}
public static void main(String[] args) {
List<TestHeepObject > heapList=new ArrayList<TestHeepObject>();
while(true){
heapList.add(new TestHeepObject());
}
}
}
package com.oom;
import com.oom.HeapOOM.TestHeepObject;
/*
* stack outof erro
*
* 方法无限递归可以测试出
* 每个main方法启动一个栈,然后不断的递归方法进入栈(栈信息保存部分方法的返回点),直到stack满发生sof异常
*
* Exception in thread "main" java.lang.StackOverflowError
*/
public class VmSOF {
public static void main(String[] args) {
new VmSOF().testSOF();
}
private void testSOF() {
testSOF();
}
}
package com.oom;
import java.util.ArrayList;
/*
*
* 不断增加常量到常量池出现OOM异常
* Exception in thread "main" java.lang.OutOfMemoryError: PermGen space
*/
public class RuntimeConstantPoolOOM {
public static void main(String[] args) {
/*al引用到常量池,保证不被gc回收。因为现在部分商用的JVM在实现永久区域的时候会full gc了。
* 常量是存储在堆中的永久区。
*/
ArrayList<String> al=new ArrayList<String>();
int i=0;
while(true){
al.add(String.valueOf(i++).intern()); //intern将字符串迁移到常量池
}
}
}
package com.oom;
/*
* 创建线程造成oom
* 这个还是不要测试了。如果你的机器够强筋,算我没说~~~
* 话说我重启了~~
*
*/
public class CreateTheadOOM {
private static void loop() {
while(true){
}
}
private void runThead() {
while(true){
new Thread(new Runnable() {
public void run() {
loop();
}
}).start();
}
}
public static void main(String[] args) {
new CreateTheadOOM().runThead();
}
}
还有通java直接内存的oom和CGlib给方法区加载class造成的oom。