gpt4 book ai didi

Java程序故意填满PermGen?

转载 作者:搜寻专家 更新时间:2023-11-01 02:08:48 24 4
gpt4 key购买 nike

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

为了全面测试这个,我需要重现这个 PermGen 的完整场景。 如何故意填充 PermGen?如果重要的话,我目前正在使用 Java 1.7.0_45。我已经编写了一个程序来填充堆,但这对我来说是一个新程序,我想我会求助于 SO。它可能更棘手(不确定)它需要是我可以部署到 GF 中的东西(.war?)。感谢任何帮助,非常感谢。

最佳答案

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

方法: ClassGenerator 类在 while 循环中创建一个新的类加载器,并一遍又一遍地加载相同的类,直到用完 permgen。现在您会注意到有一个列表保留了已加载类的引用。那是为了防止 JVM 卸载那些类:)。

文件说明
第一张图片显示,当您运行该程序时,它会用完 permgen 空间。如果你想在 Eclipse 中设置它,第二张图片显示了项目的结构。我在 eclipse 中对其进行了测试,并将其导出为可运行的 jar 文件,它在这两种情况下都适用。

作为可运行的 jar 文件运行,它用完了 permgen。 Program ran out of permgen

Eclipse 项目设置

enter image description here

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

虚拟类。这可以是任何类。此类的唯一目的是多次加载。没有别的用处。此类不执行任何逻辑。主要逻辑在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();
}
}
}

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

关于Java程序故意填满PermGen?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23415288/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com