JVM调优:PermSpace溢出

xiaoxiao2021-02-28  74

引言: 在JVM中, PermSpace主要存放什么信息?如何去理解它的溢出呢?

什么是PermSpace?

   PermSpace主要是存放静态的类信息和方法信息,静态的方法和变量,final标注的常量信息等。

PermSpace溢出的Case 1:

   这里的JDK版本1.6.0_45(jdk7/jdk8不存在类似问题)

 Opertion System: Ubuntu 14.04

  JVM 参数: -Xmx128m -Xms64m -XX:PermSize=5m -XX:MaxPermSize=10M

 利用的原理:在Java中,String类型的常量字符串信息会被存放到PermSpace区域中,形成常量池同时其并不会被GC进行回收,故此利用循环创建常量信息来达到PermSpace溢出的目的。

[java]  view plain  copy import java.util.ArrayList;   import java.util.List;      public class PermSpaceStringConstant {          public static void main(String[] args) {            List<String> strs = new ArrayList<String>();            int i = 0;                        while(true) {                strs.add(String.valueOf(i++).intern());                 System.out.println("We have created " + i + " constant String.");            }       }   }     运行结果:    

 

PermSpace溢出的Case 2:

  JVM: jdk1.6.0_45,  Operation System: Ubuntu 14.04

  JVM 参数: -Xmx128m -Xms64m -XX:PermSize=5m -XX:MaxPermSize=5M

 第三方类库: cglib-nodep-3.1.jar

  利用的原理: PermSpace存放类的信息,故此利用cglib动态创建新的类,利用循环创建足够多的类信息,充满PermSpace区域,从而达到溢出PermSpace的目的。

  源代码如下:

[java]  view plain  copy import java.lang.reflect.Method;      import net.sf.cglib.proxy.Enhancer;   import net.sf.cglib.proxy.MethodInterceptor;   import net.sf.cglib.proxy.MethodProxy;      public class CGLibTest {          public static void main(String[] args) {           new CGLibTest().testCGLIB();       }          public void testCGLIB() {        int i = 0;        while(true) {           Enhancer enhancer = new Enhancer();           enhancer.setSuperclass(EnhancerTest.class);           enhancer.setCallback(new MethodInterceptorImpl());              EnhancerTest demo = (EnhancerTest) enhancer.create();           //demo.test();           //System.out.println(demo);           System.out.println("Create " + (i++) +" instance:" + demo.getClass().getSimpleName());        }       }              static class EnhancerTest {                   }          private static class MethodInterceptorImpl implements MethodInterceptor {           @Override           public Object intercept(Object obj, Method method, Object[] args,                   MethodProxy proxy) throws Throwable {               //System.err.println("Before invoke " + method);               Object result = proxy.invokeSuper(obj, args);               //System.err.println("After invoke" + method);               return result;           }       }   }  

运行结果:

 

 总结:

   通过以上2个Cases来分析,可以更加深刻的了解PermSpace所存放的信息内容了:类信息和常量静态的信息。

转载请注明原文地址: https://www.6miu.com/read-67119.html

最新回复(0)