Metaspace && Heap space的内存溢出

Metaspace && Heap space的内存溢出


Metaspace内存溢出

如下面代码,模拟meta space的内存溢出,

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===========

你可能感兴趣的:(Metaspace && Heap space的内存溢出)