java堆溢出
public class HeapOOM {
static class OOMObject{
}
public static void main(String[] args) {
List<OOMObject> list=new ArrayList<OOMObject>();
while (true){
list.add(new OOMObject());
}
}
}
设置参数
-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
//-XX:+HeapDumpOnOutOfMemoryError 内存溢出时dump出当前内存转储快照以便分析
抛出异常
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid16032.hprof ...
Heap dump file created [28242928 bytes in 0.083 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3210)
at java.util.Arrays.copyOf(Arrays.java:3181)
at java.util.ArrayList.grow(ArrayList.java:261)
at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235)
at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227)
at java.util.ArrayList.add(ArrayList.java:458)
at test1227.HeapOOM.main(HeapOOM.java:14)
虚拟机和本地方法栈溢出
栈溢出 -Xss设置栈容量大小
单线程只抛出stackoverflow异常
public class JavaVMStackSOF {
private int stackLength=1;
public void stackLeak(){
stackLength++;
stackLeak();
}
public static void main(String[] args) throws Throwable{
JavaVMStackSOF oom=new JavaVMStackSOF();
try {
oom.stackLeak();
}catch (Throwable e){
System.out.println("stack length"+oom.stackLength);
throw e;
}
}
}
设置参数-Xss128k 减少栈内存容量
stack length990
Exception in thread "main" java.lang.StackOverflowError
at test1227.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:6)
at test1227.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:7)
at test1227.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:7)
at test1227.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:7)
创建线程导致内存溢出异常
(不要在windows上执行这段代码)
public class JavaVMStackOOM {
private void dontStop(){
while (true){
}
}
public void stackLeakByThread(){
while (true){
Thread thread=new Thread(new Runnable() {
@Override
public void run() {
dontStop();
}
});
thread.start();
}
}
public static void main(String[] args) {
JavaVMStackOOM oom=new JavaVMStackOOM();
oom.stackLeakByThread();
}
}
方法区
/**
* @description: VM Args:-XX:PermSize=10M -XX:MaxPermSize=10M jdk1.6及之前版本
* @author: icecrea
* @create: 2018-10-17 17:22
**/
public class RuntimeConstantPoolOOM {
public static void main(String[] args) {
//使用list保持常量池引用,避免full gc回收常量池行为
List<String> list=new ArrayList<>();
//10MB的PermSize在integer范围足够产生OOM
int i=0;
while(true){
list.add(String.valueOf(i++).intern());
}
}
}
使用Cglib使方法区出现内存溢出异常
在动态生成大量class的应用中,注意类的回收状况。这类场景除cglib字节码增强和动态语言外,还有大量jsp或动态产生jsp文件的应用
/**
* @description: VM Args:-XX:PermSize=10M -XX:MaxPermSize=10M
* @author: icecrea
* @create: 2018-10-17 17:47
**/
public class JavaMethodAreaOOM {
public static void main(final String[] args) {
while (true){
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(HeapOOM.OOMObject.class);
enhancer.setUseCache(false);
enhancer.setCallback(new MethodInterceptor() {
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
return methodProxy.invokeSuper(o,args);
}
});
enhancer.create();
}
}
static class OOMObject{
}
}
本机直接内存溢出
/**
* @description: -Xmx20M -XX:MaxDirectMemorySize=10M
* @author: icecrea
* @create: 2018-10-17 17:57
**/
public class DirectMemoryOOM {
private static final int _1MB=1024*1024;
public static void main(String[] args) throws IllegalAccessException {
Field unsafeField= Unsafe.class.getDeclaredFields()[0];
unsafeField.setAccessible(true);
Unsafe unsafe=(Unsafe)unsafeField.get(null);
while(true){
unsafe.allocateMemory(_1MB);
}
}
}