JVM--内存区域与内存溢出异常

2018-11-15  本文已影响0人  DiDu小梁

java是一门内存动态分配、垃圾自动回收的高级编程语言。

1 运行时数据分区

image

用来存储已被虚拟机加载的类信息、常亮、静态变量、即时编译后的代码等数据;在hotspot虚拟机中又被称为永久代,此外字符串常量池已经在java7版本后移除永久代。

运行时常量池是方法区的一部分,具有动态性,用于存放编译器生成的各种字面量和符号引用。

内存中最大的一块,用于存放对象实例,是垃圾回收的主要区域;可分为新生代、老年代,也可分为Eden空间、From Survivor空间、ToSurvivor空间。

为虚拟机执行java方法服务,描述java方法执行的内存模型,每个方法执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口灯信息;方法的调用到执行完成对应的就是入栈到出栈的过程。

为虚拟机使用到的Native方法服务;常用的hotspot虚拟机将虚拟机栈和本地方法栈合为一。

当前线程所执行的字节码的行号指示器。

2 HotSpot虚拟机对象探秘

2.1 对象的创建

假设类加载步骤已完成,还需要如下过程:

其中为新生对象分配内存有两种方式:其一,指针碰撞,这种情况要求堆内存绝对规整,用过的和空闲的分别存放,只需指针在空闲空间移动相应大小即可;其二,空闲列表,虚拟机维护一个记录内存状态的列表,分配的时候找到一块足够大的空间划分给对象实例,并更新记录;两种方案的选择由堆是否规整决定,堆的状态又由具体的垃圾收集器绝定。

此外,对象创建是一个非常频繁的动作,需要采取措施保证线程安全。此处同样有两种方案可选,其一,同步分配空间,采用CAS配上失败重试的方式保证原子性操作;其二,分配动作按照线程在不同的空间进行划分,每个线程在堆中预先分配一小块内存( Thread Local Allocation Buffer,TLAB),只有当TLAB用完并分配新的TLAB时才需要同步锁。

2.2 对象的内存布局

在HotSpot虚拟机中,对象在内存中分为三个区域:对象头、实例数据和对齐填充。

2.3 对象的访问定位

建立对象是为了使用对象,java程序需要通过栈上的reference数据来操作对上的具体对象,目前主流方式有使用句柄、直接指针两种方式。

image image

3 OutOfMemoryError异常

上一篇下一篇

猜你喜欢

热点阅读