Metaspace 元空间¶
-
JVM参数
-XX:MetaspaceSize=8m -XX:MaxMetaspaceSize=8m -
Java 8 之后的版本使用Metaspace来替代永久带.
-
Meatspace是方法区在HotSpot中的实现 , 它与持久带最大的区别在于 : Metaspace 并不在虚拟机内存中而是使用本地内存
-
即在 java 8 中, classe metadata (the virtual machines internal presentation of java class) , 被存储在叫做Metaspace的Native memory 中
-
永久代 (java 8 后被元空间替代了)存放了以下信息:
- 虚拟机加载的类信息
- 常量池
- 静态变量
- 即时编译后的代码
模拟Metaspace空间溢出 , 我们不断地生成类王远空间里灌 , 类占据的空间总是会超过Metaspace指定的空间大小
示例¶
-
调小元空间大小 (以便观察)
-XX:MetaspaceSize=8m -XX:MaxMetaspaceSize=8m -
引入GCbil
```java import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class metaspace { static class OOMTest{} public static void main(String[] args) throws Exception { int i = 0; try { while (true){ i++; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(OOMTest.class); enhancer.setUseCache(false); enhancer.setCallback(new MethodInterceptor() { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { return methodProxy.invokeSuper(o,args); } }); enhancer.create(); } } catch (Throwable e) { System.out.println("****************第" + i + "发生异常"); e.printStackTrace(); } } }
```
cmd ****************第73发生异常 java.lang.OutOfMemoryError: Metaspace at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:348) at net.sf.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:467) at net.sf.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:339) at net.sf.cglib.proxy.Enhancer.generate(Enhancer.java:492) at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:117) at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:294) at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:480) at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:305) at metaspace.main(metaspace.java:23)