当PermGen已满时,Glassfish有时无法停止,在这种情况下asadmin stop-domain domain1
不起作用。在Glassfish 2.1.1中它会永远坐在那里;在3.x中它在AS_ADMIN_READTIMEOUT
之后超时。所以我现在正在研究我的Glassfish停止脚本,它会在一定的超时后杀死/杀死它 - 以确保它被停止。
要完全测试这个,我需要重现这个PermGen完整场景。 我如何刻意填写PermGen?如果重要的话,我目前正在使用Java 1.7.0_45。我写了一个程序来填满堆,但对我来说这是一个新的程序,我想我会转向SO。它可能更棘手(不确定)它需要是什么(.war?)我可以部署到GF。非常感谢任何帮助。非常感谢。
答案 0 :(得分:6)
我有一些东西给你。我不知道如何在这里上传jar文件,所以只需在这里添加文件。
方法: ClassGenerator类在while循环中创建一个新的类加载器,并反复加载同一个类,直到它耗尽permgen。现在您将注意到有一个列表可以保存已加载类的引用。那是为了防止JVM卸载这些类:)。
文件说明
第一张图显示,当您运行程序时,它会耗尽permgen空间。如果要在eclipse中设置它,则第二个图像显示项目的结构。我在eclipse中测试它并将其导出为可运行的jar文件,它在两种情况下均可用。
作为可运行的jar文件运行,并且它用完了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<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();
}
}
}
希望它可以帮助您测试服务器崩溃。