深入理解Java虚拟机-Java内存区域、对象创建及访问

1,运行时数据区域包括:方法区,虚拟机栈,本地方法栈,堆,程序计数器,如下图1

图1,Java虚拟机运行时数据区

《深入理解Java虚拟机-Java内存区域、对象创建及访问》

    1.1,程序计数器(Program Counter Register),是一块较小的内存空间,可以看做是当前线程所执行字节码的行号表示器。唯一不会抛出OOM异常的区域。

    1.2,Java虚拟机栈(Java Virtual Machine Stacks),线程私有的,生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。会抛出StackOverflowError异常,和OOM异常。

    1.3,本地方法栈(Native Method Stack)

    1.4,Java堆(Java Heap),Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建,几乎所有的对象实例都在这里分配内存。Java堆也是垃圾收集器管理的主要区域,因此也被称为“GC堆”。

    1.5,方法区(Method Area),各个线程共享的内存区域,用于存储已被虚拟机加载的类信息、常亮、静态变量、即时编译器编译后的代码等数据。在HotSpot虚拟机上,被很对人称为“永久代”。会抛出OOM异常。

    1.6,运行时常量池(Runtime Constant Pool),用户存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。会抛出OOM异常。

2,对象创建

    2.1,虚拟机遇到new关键字,首先检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查对应的类是否已经被加载、解析和初始化。如果没有,首先执行相应的类加载过程。

    2.2,虚拟机为新生对象分配内存,分配内存的方式分为“指针碰撞”和“空闲列表”,具体用哪一种取决于虚拟机使用的GC算法是否带有压缩功能.

        2.2.1,指针碰撞:所有用过的内存放一边,没有使用的空闲内存放一边,通过一个指针作为分界点的指示器,通过移动指针来分配内存。

        2.2.2,空闲列表:空闲内存不是连续的,虚拟机维护一个列表记录哪些内存是可用的,分配内存的时候,在列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录。

    2.3,内存分配是采用CAS来保证指针在多线程使用上的安全性,另外一种采用本地线程分配缓存(Thread Local Allocation Buffer, TLAB)。虚拟机是否需要启用TLAB,使用参数-XX+/-UseTLAB来设定。

3,对象访问定位,有两种方式,通过句柄访问和通过直接指针访问。Hotspot虚拟机采用的是直接指针访问。如下图2,图3

图2,通过句柄访问对象

《深入理解Java虚拟机-Java内存区域、对象创建及访问》

图3,通过直接指针访问对象

《深入理解Java虚拟机-Java内存区域、对象创建及访问》

 

    原文作者:java虚拟机
    原文地址: https://blog.csdn.net/tidu2chengfo/article/details/83721837
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞