Java program to deliberately fill up PermGen?

前端 未结 1 677
轮回少年
轮回少年 2021-02-10 12:36

Glassfish sometimes fails to stop when the PermGen is full, in this case asadmin stop-domain domain1 doesn\'t work. In Glassfish 2.1.1 it would just sit there forev

1条回答
  •  清酒与你
    2021-02-10 12:53

    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. Program ran out of permgen

    Eclipse Project setup

    enter image description here

    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> classList = new ArrayList>();
    
        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.

    0 讨论(0)
提交回复
热议问题