我想知道你自己是如何引起OutOfMemoryError: Metaspace异常的?有没有可能加载很多类,并让它们在内存中停留很长时间。
发布于 2018-10-05 17:00:17
只要一直向StringBuilder追加一些文本,直到得到OutOfMemoryError为止
StringBuilder s = new StringBuilder();
while (true) {
s.append("dummy");
}您还可以向List或Set添加一些虚拟类,但创建新实例更耗时,并且您必须等待一段时间,直到获得OutOfMemoryError。
此外,插入到数组列表中的分期时间成本也将产生差异。
已更新
缺省情况下,Java8对Metaspace的最大大小没有限制,所以只要不使用MaxMetaspaceSize标志设置限制,就不会抛出错误。
发布于 2018-10-05 17:25:08
要创建OutOfMemoryError: Metaspace,请使用javassist.ClassPool库。下面的示例将创建Metaspace错误。
import javassist.ClassPool;
public class OutOfMemoryErrorMetaspace {
//ClassPool objects hold all the CtClasses.
static ClassPool classPool = ClassPool.getDefault();
public static void main(String[] args) throws Exception {
for (int i = 0; i < 1000000; i++) {
//makeClass method - Creates a new class (or interface) from the given class file.
Class clas = classPool.makeClass(
i + " outofmemory.OutOfMemoryErrorMetaspace ").toClass();
//Print name of class loaded
System.out.println(clas.getName());
}
}
}发布于 2020-04-05 18:54:59
为了模拟java.lang.OutOfMemoryError: Metaspace,您必须加载许多不同的类。
首先,必须设置以下元空间设置:
-XX:MaxMetaspaceSize=10m
-XX:MetaspaceSize=2M
-XX:MaxMetaspaceFreeRatio=1
-XX:MaxMetaspaceExpansion=1K
-XX:MinMetaspaceFreeRatio=1
-XX:InitialBootClassLoaderMetaspaceSize=2M然后,下面的代码使类加载器加载了许多不同的类。这是通过获取类mypackage.Myclass0的已编译字节码,并通过更改类名和调整类名的长度来调整以迭代方式创建新类来实现的:
public static void main(String[] args) throws Exception {
String clazzBase64 ="yv66vgAAADcADAEAEm15cGFja2FnZS9NeWNsYXNzMAcAAQEAEGphdmEvbGFuZy9PYmplY3QHAAMBAApTb3VyY2VGaWxlAQANTXljbGFzczAuamF2YQEABjxpbml0PgEAAygpVgwABwAICgAEAAkBAARDb2RlACEAAgAEAAAAAAABAAEABwAIAAEACwAAABEAAQABAAAABSq3AAqxAAAAAAABAAUAAAACAAY=";
byte[] compiledClazz = Base64.getDecoder().decode(clazzBase64);
int classNameLength = Integer.valueOf(compiledClazz[12]);
MyClassLoader myClassLoader = new MyClassLoader(Thread.currentThread().getContextClassLoader());
for (int i = 0; ; i++) {
byte[] bytes = String.valueOf(i).getBytes();
byte[] bytecode = new byte[compiledClazz.length + bytes.length - 1];
System.arraycopy(compiledClazz, 0, bytecode, 0, 30);
bytecode[12] = (byte) (classNameLength + bytes.length - 1 & 0xFF);
System.arraycopy(bytes, 0, bytecode, 30, bytes.length);
System.arraycopy(compiledClazz, 31, bytecode, 30 + bytes.length, compiledClazz.length - 31);
String classname = "mypackage.Myclass" + i;
Class c = myClassLoader.getClass(classname, bytecode);
}
}
public static class MyClassLoader extends ClassLoader {
public MyClassLoader(ClassLoader parent) {
super(parent);
}
public Class<?> getClass(String name, byte[] code) {
return defineClass(name, code, 0, code.length);
}
}https://stackoverflow.com/questions/52661753
复制相似问题