JAVA内存区域与内存溢出异常

JAVA运行时将内存分为5个区域:方法区 堆 虚拟机栈 本地方法栈 程序计数器 其中方法区和堆属于执行引擎 其他属于本地库接口
1.1 程序计数器
程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。而字节码解释器是程序控制流的指示器,分支,循环,跳转,异常处理,线程恢复等基础功能都需要十分依赖这个计数器来完成。为了线程切换后能恢复到正确的位置,每条线程都需要一个独立的程序计数器。这个内存区域是Java虚拟机规范中没有规定任何内存溢出情况的区域。
1.2 Java虚拟机栈
和程序计数器一样都是线程私有的,它的生命周期与线程相同。而与对象内存分配关系最密切的区域是堆和栈。栈更多情况下指虚拟机存放局部变量表部分 存放了基本数据类型,其中的储存空间以局部变量槽表示会占用,long和double会占用两个变量槽,其余的只占用一个。此区域会存在栈异常和内存溢出异常
1.3 本地方法栈
虚拟机栈执行字节码服务,本地方法栈执行执行本地方法服务。和虚拟机栈抛出的异常相同。
1.4 Java堆
是虚拟机锁管理内存中最大一块。Java堆是被所有线程共享的一块内存区域,此区域的唯一目的就是存放对象实例。 Java堆也是垃圾收集管理的区域,因此也被一些人称为GC堆。从内存分配角度看,所有线程共享的Java堆中可以划分出多个线程私有的分配缓冲区,提升分配的效率。但是无论如何划分,储存的对象只能是对象的实例。Java堆可以扩展(通过-Xmx和-Xms设定)也可以固定。存在内存溢出的异常。
1.5 方法区
是各个线程共享的内存区域,用于储存已经被虚拟机加载的类型信息,常量,静态变量,即实时编译器编译后的代码缓存等数据。和“永久代”的概念不一样,这个区域内存回收目标主要是针对常量池的回收和对类型的卸载,但是效果不太令人满意,尤其是对类型的卸载。存在内存溢出异常。
1.6 运行池常量
方法区的一部分,用于存放编译器生成的各种字面量与符号引用。相对于Class文件池常量的另外一个重要特征是具备动态性,受到方法区的内存限制。
1.7 直接内存
不是虚拟机运行数据的一部分,但是会被频繁的使用。提高性能,避免Java堆和native堆来回复制数据。,但是本机的内存分配不会受到Java堆大小的限制。
2.1 对象的创建
当虚拟机收到new指令时,首先检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载过,解析和初始化。类加载检查通过后,虚拟机会为其分配内存。由于对象创建是很频繁的行为,所以在并发情况下也不是线程安全的。解决:1)CAS操作 2)预先分配 称为本地本地线程分配缓冲。
2.2 对象的内存布局
对象在堆内存中的储存布局可以划分为三个部分:对象头,实例数据,对齐填充。
a 对象头: 1)用于储存对象自身的运行数据,如哈希码,GC分代年龄,多线程持有的锁… 2)类型指针:对象指向它的类型元数据的指针。
对象的第三部分是对象填充没啥特别含义,只是起到占位符的作用
2.3对象的访问定位
主流的访问方式主要使用句柄和直接指针两种:
1)句柄访问:Java堆划分一部份区域作为橘饼池,reference中存储的就是对象的句柄地址,而句柄中包含了对象实例数据和类型数据各自具体的地址信息。
好处:移动时只需要改变句柄中的实例数据指针。
在这里插入图片描述

2)直接指针:reference中储存的直接就是对象地址。
好处:速度快,节省了一次指针定位的时间开销。在这里插入图片描述
2.4Java堆溢出
引发原因:随着对象容量的增加,触及到最大堆的容量产生内存溢出异常
如何解决:通过内存映像分析工具 分析是内存泄漏(GC Roots引用链找到具体位置)还是内存溢出(通过-Xmx和-Xms设定)
2.5 虚拟机栈和本地方法栈溢出
1)线程请求的栈深度大于虚拟机所允许的最大深度
2)动态扩展到无法申请到足够的内存时
不同的操作系统栈容量最小值可能会有所限制主要取决于操作系统内存的分页大小
2.6 方法区和运行时常量池溢出
inter方法:如果字符串常量池中包含一个等于String对象的字符串,则返回此对象的引用,否则将此对象包含的字符串添加到常量池,返回此对象的String引用。jdk6和jdk7会产生差异。方法区溢出是一种常见的内存溢出异常,
2.7本机直接内存溢出
直接内存可以通过-XX:MaxDirectMemorySize参数来指定,如果不指定,默认与Java堆的最大值一致,体现了设计者只希望只有虚拟机标准类库里面的类才能使用Unsafe的功能。
由直接内存导致的溢出,明显的特征是在Heap Dump文件中不会看见有啥明显的情况

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值