Java program to deliberately fill up PermGen?

风格不统一 提交于 2019-12-03 08:25:16
vkg

I have some thing for you. I don't know how to upload a jar file here so just adding files here.

Approach: ClassGenerator class creates a new class loader in a while loop and loads the same class over and over again until it run out of permgen. Now you will notice there is a list that keeps a reference of the loaded class. That is to prevent JVM from unloading those classes :).

Files Explained
The first image shows that when you run the program it run out of permgen space. Second image shows the structure of the project if you want to set it up in eclipse. I tested it within eclipse and exported it as a runnable jar file it works in both cases.

Run as a runnable jar file and it ran out of permgen.

Eclipse Project setup

ClassGenerator class

package com.vkg;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class ClassGenerator {
    private static final int BUFFER = 1024;
    private List<Class<?>> classList = new ArrayList<Class<?>>();

    public static void main(String[] args) {
        ClassGenerator classGenerator = new ClassGenerator();
        // Load just some class with class loaders until perm gen space fills.
        while (true) {
            classGenerator.classLoader();
        }
    }

    private void classLoader() {
        ClassLoader classLoader = new ClassLoader() {
            public Class<?> loadClass(String classNameWithPackage)
                    throws ClassNotFoundException {
                if (!classNameWithPackage.contains("DummyClass")) {
                    return super.loadClass(classNameWithPackage);
                }
                String className = classNameWithPackage.replace('.', '/')
                        + ".class";
                byte[] classData = null;
                InputStream inputStream = null;
                try {
                    inputStream = getResourceAsStream(className);
                    byte[] buffer = new byte[BUFFER];
                    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                    int bytesRead = -1;
                    while ((bytesRead = inputStream.read(buffer, 0, BUFFER)) != -1) {
                        outputStream.write(buffer, 0, bytesRead);
                    }
                    classData = outputStream.toByteArray();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (inputStream != null) {
                        try {
                            inputStream.close();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
                Class<?> c = defineClass(classNameWithPackage, classData, 0,
                        classData.length);
                resolveClass(c);
                System.out
                        .println("Steve I am loading another copy of Dummy class. Soon Permgen will fill.");
                classList.add(c);
                return c;
            }
        };

        try {
            Class.forName("com.vkg.DummyClass", true, classLoader);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Dummy class. This can be any class. Sole purpose of this class is to get loaded large number of times. No other use. No logic gets executed from this class. Main logic is in ClassGenerator.java

package com.vkg;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class DummyClass {
    public void classLoader() {
        ClassLoader classLoader = new ClassLoader() {
            public Class<?> loadClass(String classNameWithPackage) throws ClassNotFoundException {
                 if(!classNameWithPackage.contains("DummyClass")) {
                     return  super.loadClass(classNameWithPackage);
                 } 
                 String className = classNameWithPackage.replace('.', '/') + ".class";
                byte[] classData = null;
                try {
                    InputStream inputStream = getResourceAsStream(className);
                    byte[] buffer = new byte[1];
                    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                    int bytesRead = -1;
                    while ((bytesRead = inputStream.read(buffer, 0, 1)) != -1) {
                        outputStream.write(buffer, 0, bytesRead);
                    }
                    classData = outputStream.toByteArray();
                }
                catch (IOException e) {
                    e.printStackTrace();
                }

                Class<?> c = defineClass(classNameWithPackage, classData, 0, classData.length);
                resolveClass(c);
                System.out.println("Steve I am loading another copy of Dummy class. Soon Permgen will fill.");
                return c;
            }
        };

        try {
            Class.forName("com.vkg.DummyClass", true, classLoader);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Hope it helps you test your server crash.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!