原 OutOfMemoryError系列(六):java.lang.OutOfMemoryError: Metaspace
						
							版权声明:本文为博主原创文章,请尊重他人的劳动成果,转载请附上原文出处链接和本声明。
						
						
							本文链接:https://www.91mszl.com/zhangwuji/article/details/1180
						
						
						
一:在java8 以后的版本使用Metaspace来替代永久代。Metaspace是方法区在HotSpot中的实现,它与持久代最大的区别在于:Metaspace并不在虚拟机内存中而是使用本地内存,也就是在java8中,class metadata(the virtual machines internal presentation of java class),被存储在叫做Metaspace的native memory。永久代存放了以下信息:1 虚拟机加载的类信息。2 常量池。3 静态变量。4 即时编译后的代码。
二:代码演示
package com.mszl.oom;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
 * 功能:模拟Metaspace空间溢出,我们不断生成类往元空间灌,类占据的空间总是会超过Metaspace指定的空间大小
 * 备注:更多资料请访问 http://www.91mszl.com
 * @author bobo teacher
 */
public class MetaspaceDemo {
	static class msTest{}
	
	public static void main(String[] args) {
		int i=0; // 模拟计数多少次以后发生异常
		
		try{
			while(true){
				i++;
				Enhancer ec=new Enhancer();
				ec.setSuperclass(msTest.class);
				ec.setUseCache(false);
				ec.setCallback(new MethodInterceptor() {
					
					@Override
					public Object intercept(Object o, Method method, Object[] object, MethodProxy methodProxy) throws Throwable {
						return methodProxy.invokeSuper(o, args);
					}
				});
				ec.create();
			}
		} catch(Throwable e){
			System.out.println("多少次后发生异常" + i);
			e.printStackTrace();
		}
		
		
		
	}
}通过 java -XX:+PrintFlagsInitial 命令我们可以看到自己电脑对应的Metaspace大小为12m

我们将eclipse中的jvm参数的Metaspace设置小一点,方便演示。
-XX:MetaspaceSize=5m -XX:MaxMetaspaceSize=5m执行结果
Caused by: java.lang.OutOfMemoryError: Metaspace
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
	... 11 more2020-03-26 14:51:46 阅读(2306)
名师出品,必属精品 https://www.91mszl.com