您的位置:首页 > 其它

生成内存溢出 demo

2016-04-30 17:36 302 查看
今天闲来无聊,写了几个内存溢出的demo。只要将内存设置的很小,生成的对象很多,GC无法回收便会出现内存溢出。下面是我设置的vmArgs

-Xmx10m (最大堆内存)

-Xms10m (初始堆内存)

-Xmn5m (新生代堆内存,剩余的就是老年代=xmx-xmn)

-XX:PermSize=5m (永久代初始内存)

-XX:MaxPermSize=5m (永久代最大内存)

-XX:MaxDirectMemorySize=2m (堆外内存)

-XX:SurvivorRatio=8 (分配策略)

-XX:+HeapDumpOnOutOfMemoryError (出现内存溢出时打印快照)

-XX:HeapDumpPath=c:\temp\ (打印快照的地址,若不填写默认生成在项目的根目录)

-XX:+PrintGCDetails(打印GC日志)

package com.jvm.out_of_memory_error;

import org.junit.Test;
import sun.misc.Unsafe;
import sun.net.www.protocol.jar.URLJarFile;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;

/**
* 内存溢出
* vmArgs -Xmx10m -Xms10m -Xmn5m -XX:PermSize=5m -XX:MaxPermSize=5m -XX:SurvivorRatio=8 -XX:MaxDirectMemorySize=2m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=c:\temp\ -XX:+PrintGCDetails
*/
public class OutOfMemoryError {

/**
* 大对象申请不到空间溢出
*/
//@Test
public void HeapOutOfMemoryError() {
byte[] bufOne = new byte[1024 * 1024 * 4];
byte[] bufTwo = new byte[1024 * 1024 * 4];
}

/**
* 常量池内存溢出
* 只要把常量池中的对象加入引用无法被jvm回收即可
* 1.7 将常量池移入到heap区域,所以显示的是heap 溢出
* 若是1.6则显示 java.lang.OutOfMemoryError: PermGen space
*/
//@Test
public void constantsPoolOutOfMemeryError() {
long i = 0;
String a = "";
List<String> strings = new ArrayList<>(100000);
for (;;) {
a = getClass() + String.valueOf(i);
a.intern();
strings.add(a);
i ++;
}
}

/**
* 栈溢出 递归调用达到栈的最大深度
*/
//@Test
public void StackOverflowError() {
StackOverflowError();
}
/**
* 永久代存储的是类信息,只要加载无限多的类则永久代溢出
*/
//@Test
public void permGenOutOfMemoryError() throws Exception{
URLJarFile urlJarFile = new URLJarFile(new File("C:\\Program Files\\Java\\jdk1.7.0_71\\jre\\lib\\rt.jar"));
Enumeration<JarEntry> jarEntry = urlJarFile.entries();
for (JarEntry entry = null; jarEntry.hasMoreElements();entry = jarEntry.nextElement()) {
String clsName = String.valueOf(entry);
if (clsName != "null" && !clsName.contains("META-INF") && !clsName.contains("$")) {
String finalName = clsName.replace("/",".");
finalName = finalName.substring(0,finalName.indexOf(".class"));
Class<?> cls = getClass().getClassLoader().loadClass(finalName);
if (cls.getDeclaringClass() != null && cls.getDeclaringClass().getModifiers() == Modifier.PUBLIC) {
cls.newInstance();
}
}
}
}

/**
* DirectMemory 默认不指定则跟java堆最大值相等 当然也受限于本身电脑内存
* 指定MaxDirectMemorySize=2m
* @throws Exception
*/
@Test
public void directBufferOutOfMemoryError() throws Exception{
ByteBuffer.allocateDirect(2 * 1024 * 1024);
// 下面使用unsafe类分配内存,则只受限于电脑内存
/*Field field = Unsafe.class.getDeclaredFields()[0];
field.setAccessible(true);
Unsafe unsafe = (Unsafe)field.get(new Object());
unsafe.allocateMemory(100 * 1024 * 1024);*/
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: