Metaspace && Heap space的内存溢出
note that when the heap space runs out you get
java.lang.OutOfMemoryError: Java heap space
However when you run out of PermGen you get
java.lang.OutOfMemoryError: PermGen space
However in jdk8 when you run out of Metaspace you get
java.lang.OutOfMemoryError: Metaspace
Metaspace内存溢出
如下面代码,模拟Metaspace的内存溢出,
public interface ClassA {
void method(String input);
}
======================
public class ClassAImpl implements ClassA {
public void method(String name) {
// do nothing
}
}
======================
public class ClassAInvocationHandler implements InvocationHandler {
private Object classAImpl;
public ClassAInvocationHandler(Object impl) {
this.classAImpl = impl;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (Object.class == method.getDeclaringClass()) {
String name = method.getName();
if ("equals".equals(name)) {
return proxy == args[0];
} else if ("hashCode".equals(name)) {
return System.identityHashCode(proxy);
} else if ("toString".equals(name)) {
return proxy.getClass().getName() + "@" +
Integer.toHexString(System.identityHashCode(proxy)) +
", with InvocationHandler " + this;
} else {
throw new IllegalStateException(String.valueOf(method));
}
}
return method.invoke(classAImpl, args);
}
}
======================
public class ClassMetadataLeakSimulator {
private static Map<String, ClassA> classLeakingMap = new HashMap<String, ClassA>();
private final static int NB_ITERATIONS_DEFAULT = 50000;
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("Class metadata leak simulator");
System.out.println("Author: Pierre-Hugues Charbonneau");
System.out.println("http://javaeesupportpatterns.blogspot.com");
int nbIterations = (args != null && args.length == 1) ? Integer.parseInt(args[0]) : NB_ITERATIONS_DEFAULT;
try {
for (int i = 0; i < nbIterations; i++) {
String fictiousClassloaderJAR = "file:" + i + ".jar";
URL[] fictiousClassloaderURL = new URL[] { new URL(fictiousClassloaderJAR) };
// Create a new classloader instance
URLClassLoader newClassLoader = new URLClassLoader(fictiousClassloaderURL);
// Create a new Proxy instance
ClassA t = (ClassA) Proxy.newProxyInstance(newClassLoader,
new Class<?>[] { ClassA.class },
new ClassAInvocationHandler(new ClassAImpl()));
// Add the new Proxy instance to the leaking HashMap
classLeakingMap.put(fictiousClassloaderJAR, t);
}
}
catch (Throwable any) {
System.out.println("ERROR: " + any);
}
System.out.println("Done!");
}
}
运行上面的程序,并设置JVM参数,如下,
➜ sample java -Xmx128m -Xms128m -XX:+UseG1GC -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=64m ClassMetadataLeakSimulator
Class metadata leak simulator
Author: Pierre-Hugues Charbonneau
http://javaeesupportpatterns.blogspot.com
ERROR: java.lang.OutOfMemoryError: Metaspace
Done!
Heap space内存溢出
如下面这段代码,
import java.util.ArrayList;
import java.util.List;
public class GCTest {
public static void main(String args[]) {
List<GCTest> list = new ArrayList<>();
for (int i = 0; i < Integer.MAX_VALUE; i++) {
list.add(new GCTest());
}
}
}
运行程序并设置JVM参数,
➜ workspace java -Xmx128m -Xms128m -XX:+UseG1GC -XX:MetaspaceSize=3m -XX:MaxMetaspaceSize=3m GCTest
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3210)
at java.util.Arrays.copyOf(Arrays.java:3181)
at java.util.ArrayList.grow(ArrayList.java:261)
at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235)
at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227)
at java.util.ArrayList.add(ArrayList.java:458)
at GCTest.main(GCTest.java:10)
===========END===========