在jdk1.8的环境下模拟永久代内存溢出

相信不少小伙伴在看深入理解Java虚拟机的时候,作者给我们举例一个demo来发生PermGen space

1、通过List不断添加String.intern();

2、通过设置对应的-XX:PermSize与-XX:MaxPermSize(更快看到效果),

3、在jdk1.6的环境下会抛出OOM:PermGen space异常

public static void main(String[] args) {
    List<String> str=new ArrayList<>();
    int i=0;
    while (true){
        str.add(String.valueOf(i).intern());
    }

}

然而在jdk1.8的环境下,这段代码,会出现OOM,但不是出现PermGenSpace,而是会当堆内存不够用(-Xmx)的时候,抛出Java heap space,而且会温馨提示

ignoring option PermSize=10M; support was removed in 8.0

ignoring option MaxPermSize=10M; support was removed in 8.0

---------------------------------------------------------------------------------------------------------

首先我们看一下String.intern()方法,官方的注释是

Returns a canonical representation for the string object. A pool of strings, initially empty, is maintained privately by the class String. When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned. It follows that for any two strings s and t, s.intern() == t.intern() is true if and only if s.equals(t) is true. All literal strings and string-valued constant expressions are interned. String literals are defined in section 3.10.5 of the The Java? Language Specification.

大概意思就是,如果常量池已经存在这个string对象,那么就返回这个字符串的引用。否则将此string对象加入常量池,再返回引用

~

但是在jdk1.8中,其实已经没有永久代这一说了,取而代之的是一个叫元空间(Meta space)。而常量池放到了堆中,所以也就不会出现PermGen space了

---------------------------------------------------------------------------------------------------------

那么如果想看到metaspace的异常怎么做呢?

一个是可以把这两个值设置的足够小,那么启动就会报错了。

-XX:MetaspaceSize=3M -XX:MaxMetaspaceSize=3M

一个是可以使用jdk动态加载技术,例如cglib动态的生成大量的数据来达到

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值