Java程序故意填写PermGen?

当PermGen已满时,Glassfish有时无法停止,在这种情况下, asadmin stop-domain domain1不起作用。 在Glassfish 2.1.1中它会永远坐在那里; 在3.x中,它在AS_ADMIN_READTIMEOUT之后AS_ADMIN_READTIMEOUT 。 所以我现在正在研究我的Glassfish停止脚本,它将在一定的超时后杀死/杀死它 – 以确保它被停止。

为了完全测试这个,我需要重现这个PermGen完整场景。 我怎么刻意填写PermGen? 我现在正在使用Java 1.7.0_45,如果这很重要的话。 我写了一个程序来填满堆,但对我来说这是一个新的程序,我想我会转向SO。 它可能更棘手(不确定)它需要是什么(.war?)我可以部署到GF。 感谢任何帮助,非常感谢。

我有东西给你。 我不知道如何在这里上传jar文件,所以只需在这里添加文件。

方法: ClassGenerator类在while循环中创建一个新的类加载器,并反复加载同一个类,直到它用完permgen。 现在您将注意到有一个列表可以保存已加载类的引用。 那是为了防止JVM卸载这些类:)。

文件说明
第一张图显示,当您运行程序时,它会耗尽permgen空间。 如果要在eclipse中设置它,则第二个图像显示项目的结构。 我在eclipse中测试它并将其导出为可运行的jar文件,它在两种情况下均可用。

作为一个可运行的jar文件运行,它用完了permgen。 程序耗尽了permgen

Eclipse项目设置

在此处输入图像描述

ClassGenerator类

 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(); } } } 

虚拟课。 这可以是任何类。 这个类的唯一目的是加载大量次数。 没有其他用途。 没有逻辑从这个类执行。 主要逻辑在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(); } } } 

希望它可以帮助您测试服务器崩溃。