Java内存区域及内存溢出异常

1 运行时数据区

在这里插入图片描述
程序计数器:

是线程私有内存,用于指示当前程序所执行的字节码的行号。唯一一个java虚拟机规范没有定义任何OutOfMemoryError情况的区域。

java虚拟机栈(也就是我们平时所说的栈):

也是线程私有的,用于描述java方法执行的内存模型:每一个java方法执行时,都会建立一个栈帧,用以保存方法运行时的局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法的调用及运行完成之后的返回,都对应与一个栈帧在java虚拟机栈中的入栈和出栈。局部变量表保存了方法编译期可知的基本数据数据类型、对象的引入、返回值。Java虚拟机规范在此定义了两个可能会发出的非正常情况StackOverflowError与OutOfMemoryError。

本地方法栈:

java虚拟机栈的作用非常相似,区别在于java虚拟机栈是为虚拟机执行的java方法服务;而本地方法栈是为虚拟机所使用的Native方法服务。当然,与java虚拟机栈一样,也可能会发生StackOverflowError与OutOfMemoryError错误。

java堆:

是线程共享的,是java虚拟机所管的最大的一块内存区域,用于保存对象的实例。并且java堆是垃圾回收机制管理的主要区域。

堆还可以细分为老年代,新生代。当然当堆空间不足时会报OutOfMemoryError非正常状况。

方法区:

是线程共享的,用于保存已被java虚拟机加载了的类信息、常量、静态变量、即时编译器编译后的代码等。java虚拟机规范对方法区的规范非常松。当方法区无法满足内存分配需求时,会发生OutOfMemoryError非正常情况。

运行时常量池:

运行时常量池是方法区的一部分。Class文件除了一些描述信息之外,还有一项信息常量池(注意和运行时常量池区分)用于保存编译器生成的字面量、符号引用,在类加载之后进入方法区的运行时常量池。

直接内存区:

不属于java运行时数据区,和NIO的通道和缓冲区有关(运行分配堆外内存)。当然也会发生OutOfMemoryError。

2虚拟机对象


  下面讨论的是Hotspot中对象的创建。

2.1 对象的创建


遇到new指令时:

首先检查命令的参数是否可以在常量池定位一个类的符号引用,并且检查符号引用对应的类是否已经加载。若没有,那必须先进行类的加载。

类加载检查过后,为对象分配内存:

对象分配要考虑两个问题
内存分配方式:

为对象分配内存有两种方法:“指针碰撞”(堆是规整的)、“空闲列表”(堆是非规整的)。堆归不规整是由垃圾收集器是否有内存压缩整理功能决定的。

对象在分配内存时是线程不安全的:

一可以内存分配做同步控制。二是将内存分配的动作按照线程分配到不同空间进行

内存空间初始化为零:

是为了保证java对象可以在不被赋值初始化就能使用。

虚拟机对对象进行必要的设置:

对象头中设置对象的类型信息,是否启用偏向锁等。

执行init方法:

其实在上一步,在java虚拟机的角度,对象已经产生了。但是,在java程序的角度来看,还没有执行init方法,对对象进行赋值,此不按照程序员的意愿初始化对象。

2.2 对象的内存布局


  对象在内存中的存储布局分为:对象头(Object header)、实例数据(Instance data)、对齐填充(Padding)。
对象头:

对象头分为两部分:

  • 对象的第一部分用于存储对象自身运行时的数据,如哈希码、偏向锁等。
  • 对象头的另一部分是类型指针,用于指向它的类元数据,就是通过这个指针我们知道对象是哪个类的实例。

实例数据:

是对象真正存储的有效信息

对齐填充:

这部分不是必须有的,仅起到占位符的作用。因为HotSpot要求对象的地址必须是8字节的整数倍。

2.3 对象的访问定位


对象的访问控制(用于访问对象)有两种,通过句柄访问、直接指针访问。
句柄访问:

通过句柄访问,堆中必须分出一块区域来作为句柄池。对象的引用保存的是对象的句柄,句柄包含两部分(对象实例数据,对象类型数据)。
通过句柄访问对象

直接指针访问:

使用直接指针访问,那么堆就要考虑怎样访问对象的类型信息了(访问方法区)
直接指针访问

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值