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

[size=x-large][color=red][quote]方法区和运行时常量池溢出 ide配置参考堆溢出 附件[/quote][/color][/size]


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

*/


[size=x-large][color=red][quote]下面是测试1.8中和1.7中还有1.6中引用的不同[/quote][/color][/size]


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



[size=medium]
[color=brown]jdk1.6 中运行 intern()方法会把首次遇到的字符串实例复制到永久代中,返回的也是永久代这个字符串实例的引用,而由StringBuilder创建的字符串实例会在java堆上,所以必然不是一个引用,返回false,而1.7(以及部分其他虚拟机,例如JRockit)的intern()实现不会复制实例,只是在常量池中记录首次出现的实例引用,因此intern()返回true,str2返回false是因为“java”字符串在执行StringBuilder.toString()之前已经出现过,字符常量池总中已经有了他的引用,不符合“首次出现”所以返回false 1.8和1.7相同[/color]
[/size]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值