JVM内存区域与内存溢出异常总结

JVM内存区域

数据区域基本作用线程私有性溢出异常备注
虚拟机栈创建栈帧保存局部变量表,操作数栈,动态链接,方法出口等线程私有请求栈深度过深:StackOverFlowError异常,内存不足,OutOfMemoryError异常
本地方法栈和虚拟机栈基本一致线程私有StackOverFlowError 和OOM
程序计数器字节码执行行号指示器线程私有唯一一个没有规定任何OOM的区域
java堆存放java对象实例线程共享OOM垃圾收集器管理的主要区域
方法区存储被虚拟机加载的类信息,常量,静态变量等线程共享OOM
运行时常量池方法区的一部分,存放各种字面量和符号引用线程共享
直接内存--OOM-

JVM溢出异常

数据区域异常溢出
java堆不断创建对象,并保证对象到GC Roots对象之间有可达路径时会 OOM
虚拟机栈单线程下,无论是由于栈帧过大还是虚拟机栈容量太小,当内存无法分配时,都抛出StackOverflowError溢出。多线程下,为每个线程的栈分配的内存越大,越容易产生OOM
方法区运行时产生大量的类去填满方法区,会抛出溢出OOM
本机直接内存本机内存不足直接溢出OOM

操作数栈和局部变量表的关系

jdk1.8的java内存模型

HotShop虚拟机采用永久代实现方法区。在jdk1.7以后将永久代中的字符串常量池移到堆中。而jdk1.8采用元空间来实现方法区。jdk8不再有永久代

元空间(MetaSpace)和永久代最大的区别就是元空间使用的是本地内存。

jvm三大调优参数

堆和栈的区别

堆和栈的联系

intern

intern在jdk6之前,如果字符串没出现过,那么就把字符串放到常量池(永久代)中,并返回该引用。

jdk6以后,如果字符串没出现过,则在堆中创建该字符串对象,并把该对象的引用存在常量池中(jdK7已将常量池移到堆中)

public class RuntimeConstantPool {
    public static void main(String[] args) {
        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);
    }
}

上述代码若采用jdk6运行,则是两个false,因为itern把每出现过的字符串存在永久代中,并返回永久代中该字符串的引用,而StringBuilder创建的字符串实现在堆上,所以必定不同。

jdk7以后,会返回一个true,一个false.因为jdk不会再复制实例,只是在常量池中记录首次出现的实例引用。所以如果字符串是首次出现的话,常量池记录的便是首次出现的字符串的对象实例引用。也就是若,若是首次出现,返回True,否则返回false.

首先,通过引号引用a会将a放进常量池中,而new String(“a”)则会在堆中创建对象。所以s是堆中对象的引用,而s.intern()会尝试把s的副本放进常量池,但此时常量池已经有a了,所以放不进去。所以s2引用的是常量池中的a。所以s和s2不同。

s3引用了堆中对象aa,然后调用s3.intern()会将s3的副本放进常量池,此时常量池中还没有aa,放入成功,之后s4引用常量池中的aa,两者不同。

jdk7后。首先,通过引号引用a会将a放进常量池中,而new String(“a”)则会在堆中创建对象。所以s是堆中对象的引用,而s.intern()会尝试把s的引用放进常量池,但此时常量池已经有a了,所以放不进去。所以s2引用的是常量池中的a。所以s和s2不同。

s3引用了堆中对象aa,然后调用s3.intern()会将s3的引用放进常量池,此时常量池中还没有aa,放入成功,之后s4引用常量池中的aa,此时不管是堆中的aa还是常量池中的aa都是一样的,两者相同。

总得来说,intern在1.6之前,通过str.intern()会将存在堆中的str字符串对象的拷贝存放在字符串常量池中。而jdk1.7后。str.intern()会将堆中str字符串对象的引用放进常量池中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值