第二章:方法区和运行时常量池溢出
生活随笔
收集整理的這篇文章主要介紹了
第二章:方法区和运行时常量池溢出
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
由于運行時常量池屬于方法區(qū)的一部分,因此兩個區(qū)域放在一塊執(zhí)行。 String.intern()是一個Native方法,它的作用是如果字符串常量池中已經(jīng)包含了此String對象的字符串,則返回代表池中這個字符串的String對象;否則將此String對象包含的字符串添加到常量池中,并且返回此String對象的引用。 可以通過以下代碼測試運行時常量池溢出: public class Test {public static void main(String[] args) {int i =0;List<String> list = new ArrayList();while(true) {list.add(String.valueOf(i++).intern());}}
}
?
可以在拋出的異常后面發(fā)現(xiàn)“Perm space”信息。 可以使用String.intern()測試運行時常量池: public class Test1 {public static void main(String[] args) {String str1 = new StringBuilder("111").append("-222").toString();System.out.println(str1.intern()==str1);String str2= new StringBuilder("jav").append("a").toString();;System.out.println(str2.intern()==str2);} } 結(jié)果: true false?
JDK1.7中的intern實現(xiàn)不會復(fù)制實例,只是在常量池中記錄首次出現(xiàn)的實例引用,因此intern()返回的引用和由StringBuilder創(chuàng)建的那個字符串實例是同一個。 對str2比較返回false是因為“java”字符串在執(zhí)行StringBuilder.toString()之前已經(jīng)出現(xiàn)過了,字符串常量池中已經(jīng)有它的引用了,不符合“首次出現(xiàn)”的原則。 方法區(qū)用于存放Class相關(guān)的信息,如類名、訪問修飾符、常量池、字段描述、方法描述等,對于這些區(qū)域的測試,基本的思路是運行時產(chǎn)生大量的類填充方法區(qū),直到溢出。 可以借助GCLib直接操作字節(jié)碼運行時產(chǎn)生大量的動態(tài)類: public class Test1 { public static void main(final String[] args) { while(true){ Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(OOMOBject.class); enhancer.setUseCache(false); enhancer.setCallback(new MethodInterceptor() { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { return methodProxy.invoke(objects,args); } }); enhancer.create(); } } static class OOMOBject{} }?
除了GCLib字節(jié)碼增強和動態(tài)語言之外,常見的還有大量JSP或者動態(tài)生成JSP文件的應(yīng)用、基于OSGi的應(yīng)用等轉(zhuǎn)載于:https://www.cnblogs.com/use-D/p/10618771.html
總結(jié)
以上是生活随笔為你收集整理的第二章:方法区和运行时常量池溢出的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android系统从驱动到上层服务再到应
- 下一篇: 一起学React--组件定义和组件通讯