`
subject
  • 浏览: 39451 次
  • 性别: Icon_minigender_1
  • 来自: 墨尔本
社区版块
存档分类
最新评论

方法区和运行时常量池溢出

阅读更多
引用
方法区和运行时常量池溢出  ide配置参考堆溢出 附件


import com.google.common.collect.Lists;

import java.util.List;

/**
 * @Author admin Date: 2017/6/19 10:40
 * @description: 方法区和运行时常量池溢出  ide配置参考堆溢出 附件
 */
public class RuntimeConstantPoolOOM {

    public static void main(String[] args){
        // 使用List 保持着常量池引用,避免Full GC回收常量池行为

        List<String> list = Lists.newArrayList();

        // 10MB 的permsize 在integer 范围内足够产生OOM了

        int i= 0;
        while (true){
            list.add(String.valueOf(i++).intern());
        }
    }
}

/**jdk1.7中GC不会回收 list中添加的常量 1.8中回收了
   所以输出的错误信息 不是 permeGen space
   而是:
   [Full GC (Ergonomics) [PSYoungGen: 8191K->8191K(9216K)] [ParOldGen: 10053K->10053K(10240K)] 18245K->18245K(19456K), [Metaspace: 3439K->3439K(1056768K)], 0.0456493 secs] [Times: user=0.14 sys=0.00, real=0.05 secs] 
[Full GC (Ergonomics) [PSYoungGen: 8191K->8191K(9216K)] [ParOldGen: 10055K->10055K(10240K)] 18247K->18247K(19456K), [Metaspace: 3439K->3439K(1056768K)], 0.0464576 secs] [Times: user=0.09 sys=0.00, real=0.05 secs] 
[Full GC (Ergonomics) [PSYoungGen: 8191K->8191K(9216K)] [ParOldGen: 10056K->10056K(10240K)] 18248K->18248K(19456K), [Metaspace: 3439K->3439K(1056768K)], 0.0454579 secs] [Times: user=0.14 sys=0.00, real=0.05 secs] 
[Full GC (Ergonomics) Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
[PSYoungGen: 8191K->8191K(9216K)] [ParOldGen: 10058K->10058K(10240K)] 18250K->18250K(19456K), [Metaspace: 3439K->3439K(1056768K)], 0.0457579 secs] [Times: user=0.11 sys=0.00, real=0.05 secs] 
[Full GC (Ergonomics) 	at java.lang.Integer.toString(Integer.java:401)
[PSYoungGen: 8192K->0K(9216K)] [ParOldGen: 10075K->1049K(10240K)] 18267K->1049K(19456K), [Metaspace: 3463K->3463K(1056768K)], 0.0074261 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
Heap
	at java.lang.String.valueOf(String.java:3099)
 PSYoungGen      total 9216K, used 193K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
	at RuntimeConstantPoolOOM.main(RuntimeConstantPoolOOM.java:20)
  eden space 8192K, 2% used [0x00000000ff600000,0x00000000ff630478,0x00000000ffe00000)
  from space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
  to   space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
 ParOldGen       total 10240K, used 1049K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
  object space 10240K, 10% used [0x00000000fec00000,0x00000000fed064a8,0x00000000ff600000)
 Metaspace       used 3470K, capacity 4600K, committed 4864K, reserved 1056768K
  class space    used 377K, capacity 424K, committed 512K, reserved 1048576K

Process finished with exit code 1

*/


引用
下面是测试1.8中和1.7中还有1.6中引用的不同


import com.google.common.collect.Lists;

import java.util.List;

/**
 * @Author admin Date: 2017/6/19 10:40
 * @description: 方法区和运行时常量池溢出  ide配置参考堆溢出 附件
 */
public class RuntimeConstantPoolOOM {

    public static void main(String[] args){
//        // 使用List 保持着常量池引用,避免Full GC回收常量池行为
//
//        List<String> list = Lists.newArrayList();
//
//        // 10MB 的permsize 在integer 范围内足够产生OOM了
//
//        int i= 0;
//        while (true){
//            list.add(String.valueOf(i++).intern());
//        }

        String str1 = new StringBuilder("马云").append("马化腾").toString();
        System.out.println(str1.intern() == str1);

        String str2 = new StringBuilder("ja").append("va").toString();
        System.out.println(str2.intern() == str2);
    }
}
/**
   jdk1.6中 执行结果返回的是  false  false
   jdk1.7中 执行结果返回的是  true false
   jdk1.8中 执行结果返回的是  true false
*/

// jdk1..8如下:

true
false
Heap
 PSYoungGen      total 9216K, used 4431K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
  eden space 8192K, 54% used [0x00000000ff600000,0x00000000ffa53d90,0x00000000ffe00000)
  from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
  to   space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
 ParOldGen       total 10240K, used 0K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
  object space 10240K, 0% used [0x00000000fec00000,0x00000000fec00000,0x00000000ff600000)
 Metaspace       used 3353K, capacity 4500K, committed 4864K, reserved 1056768K
  class space    used 363K, capacity 388K, committed 512K, reserved 1048576K

Process finished with exit code 0




jdk1.6 中运行 intern()方法会把首次遇到的字符串实例复制到永久代中,返回的也是永久代这个字符串实例的引用,而由StringBuilder创建的字符串实例会在java堆上,所以必然不是一个引用,返回false,而1.7(以及部分其他虚拟机,例如JRockit)的intern()实现不会复制实例,只是在常量池中记录首次出现的实例引用,因此intern()返回true,str2返回false是因为“java”字符串在执行StringBuilder.toString()之前已经出现过,字符常量池总中已经有了他的引用,不符合“首次出现”所以返回false  1.8和1.7相同

0
2
分享到:
评论

相关推荐

    Java虚拟机

    2.4.3 方法区和运行时常量池溢出 2.4.4 本机直接内存溢出 2.5 本章小结 第3章 垃圾收集器与内存分配策略 3.1 概述 3.2 对象已死吗 3.2.1 引用计数算法 3.2.2 可达性分析算法 3.2.3 再谈引用 3.2.4 生存...

    美团和蚂蚁金服面试笔记.pdf

    堆 虚拟机栈局部变量表 运行时常量池 操作数栈主要保存计算过程的中间结果,同时作为计算过程中的变量临时的存储空间 动态连接 方法返回地址 本地方法区 程序计数器 堆讲解有限分配Eden区--&gt;空间分配担保机制 大对象...

    Java常见面试问题整理.docx

    运行时常量池是方法区的一部分,class文件除了有类的字段、接口、方法等描述信息之外,还有常量池用于存放编译期间生成的各种字面量和符号引用。在老版jdk,方法区也被称为永久代。在1.8之后,由于永久代内存经常...

    深入理解_Java_虚拟机 JVM_高级特性与最佳实践

    / 29 2.2.7 直接内存 / 29 2.3 对象访问 / 30 2.4 实战:OutOfMemoryError异常 / 32 2.4.1 Java堆溢出 / 32 2.4.2 虚拟机栈和本地方法栈溢出 / 35 2.4.3 运行时常量池溢出 / 38 2.4.4 方法区溢出 / 39 2.4.5...

    招银网络java科技笔试题-WaytoInterview:JVM和设计模式和算法的快速浏览

    运行时常量池内存溢出(在 JDK8 中,永久代已完全被元空间(Meatspace)所取代,故此处抛出错误和堆内存溢出一样) Design Pattern 各种经典的设计模式以及简单例子 工厂模式 适配器模式 过滤器模式 代理模式 MVC模式 ...

    java8源码-jvm-study:jvm-study

    java8 源码 jvm-study 方法执行过程 jvm申请内存 初始化运行时数据区 方法区:存放 class;静态变量:常量 堆:实例对象 栈:栈帧(对象的引用,方法)...常量池(方法区) class常量池 class的方法 字面量(String a =

    深入理解JVM内存结构及运行原理全套视频加资料.txt

     第28讲 Java内存区域-直接内存和运行时常量池 00:15:53  第29讲 对象在内存中的布局-对象的创建 00:21:19  第30讲 探究对象的结构 00:13:47  第31讲 深入理解对象的访问定位 00:08:01  第32讲 垃圾回收-...

    Java进阶教程解密JVM视频教程

    学习字节码指令的的运行流程,字节码指令与常量池、方法区的关系。掌握条件分支、循环控制、异常处理、构造方法在字节码级别的实现原理,利用HSDB工具理解多态原理。还会涉及从编译期的语法糖处理,到类加载的各个...

    超级有影响力霸气的Java面试题大全文档

    wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。 17、...

    java面试题

    答:1:封装:通过定义类并且给类的属性和方法加上访问控制 2:继承:子类继承父类,子类可以拥有父类中已定义的方法,并且子类可以修改父类中的方法使其更适合特殊需求。 3:多台:不同对象对统一消息作出不同...

    java 面试题 总结

    子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被"屏蔽"了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。...

    深入理解Java虚拟机视频教程(jvm性能调优+内存模型+虚拟机原理)视频教程

    第28节Java内存区域-直接内存和运行时常量池00:15:53分钟 | 第29节对象在内存中的布局-对象的创建00:21:19分钟 | 第30节探究对象的结构00:13:47分钟 | 第31节深入理解对象的访问定位00:08:01分钟 | 第32节垃圾...

Global site tag (gtag.js) - Google Analytics