您现在的位置是:主页 > 数据库技术 > 数据库技术

JVM堆中对象分配、布局和访问的概念是什么

IDCBT2022-01-07服务器技术人已围观

简介本篇内容介绍了“JVM堆中对象分配、布局和访问的概念是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情

本篇内容介绍了“JVM堆中对象分配、布局和访问的概念是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

1、对象的创建

Java 是一门面向对象的语言,Java 程序运行过程中无时无刻都有对象被创建出来。从语言层面看,创建对象只是一个 new 关键字而已,而在虚拟机中,对象(仅限于普通 Java 对象,不包括数组和 Class 对象等)的创建又是怎么一个过程呢?

以 Hotspot 虚拟机为例,当虚拟机遇到一条字节码指令,首先会检查这个指令的参数是否能在常量池中定位到一个符号引用,并检查这个符号引用代表的类是否已被加载、解析和初始化,如果没有,那么会先执行对应的类加载过程

类加载检查通过后,虚拟机将为新生对象分配内存。对象所需内存的大小在类加载过程中即可完全确定,为对象分配空间的任务实际上等同于把一块确定大小的内存区域从 Java 堆中划分出来,并分配给对象。划分内存的方式主要有两种:

    指针碰撞法

    即假设 Java 堆中内存是绝对规整的,已被使用的内存放在一边,空闲的内存放在另一边,中间有一个指针作为分界点的指示器,那么当需要分配内存时,只需要将指针向空闲空间的方向挪动一段与对象大小相等的距离即可

    空闲列表法

    这个情况就是 Java 堆中内存并不是规整的,已使用内存和空闲内存相互交错在一起。此时虚拟机必须维护一个列表,记录哪些内存块可用,分配时从列表中找出一块足够大的空间划分给对象实例,并更新列表记录

    由此可见,选择哪种分配方式由 Java 堆是否规整决定,而 Java 堆是否规整又由所采用的垃圾收集器是否带有空间压缩整理的能力决定

    除了如何划分可用空间以外,还有一个需要考虑的问题:对象创建在虚拟机中是非常频繁的行为,即使仅仅只是修改指针的位置,在并发情况下也并不是安全的,有可能出现正在给对象 A 分配内存,指针还没来得及修改,对象 B 又同时使用原来的指针来分配内存。解决该问题的方法有两个:一个是对分配内存空间的动作片进行同步处理,实际上虚拟机是采用 CAS 配上失败重试机制来保证更新操作的原子性的;另一种是把内存分配的动作按照线程划分到不同的空间之中进行,即每个线程在 Java 堆中预先分配一小块内存,称为本地线程分配缓冲(Thread Local Allocation Buffer),简称 TLAB,哪个线程要分配内存,就在哪个线程的本地缓冲区中分配,只有本地缓冲区用完了,分配新的缓冲区时才需要同步锁定。虚拟机是否使用 TLAB,可以通过 -XX:+/UseTLAB 参数来设定

    标签:

    很赞哦! ()

本栏推荐