生成内存溢出 demo

今天闲来无聊,写了几个内存溢出的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);*/
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值