JVM中对象创建与内存分配机制是如何运作的?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1495个文字,预计阅读时间需要6分钟。
创建对象+当JVM+收到一个new+指令时,会检查指令中的参数是否在常量池中存在该符号的引用,还会检查该类是否已经被加载过,如果没有的语句则需要先进行一次类加载。接着就是分配内存。
创建对象
当 JVM 收到一个 new 指令时,会检查指令中的参数在常量池是否有这个符号的引用,还会检查该类是否已经被加载过了,如果没有的话则要进行一次类加载。
接着就是分配内存了,通常有两种方式:
- 指针碰撞
- 空闲列表
使用指针碰撞的前提是堆内存是完全工整的,用过的内存和没用的内存各在一边每次分配的时候只需要将指针向空闲内存一方移动一段和内存大小相等区域即可。
当堆中已经使用的内存和未使用的内存互相交错时,指针碰撞的方式就行不通了,这时就需要采用空闲列表的方式。虚拟机会维护一个空闲的列表,用于记录哪些内存是可以进行分配的,分配时直接从可用内存中直接分配即可。
堆中的内存是否工整是有垃圾收集器来决定的,如果带有压缩功能的垃圾收集器就是采用指针碰撞的方式来进行内存分配的。
分配内存时也会出现并发问题:
这样可以在创建对象的时候使用 CAS 这样的乐观锁来保证。
也可以将内存分配安排在每个线程独有的空间进行,每个线程首先在堆内存中分配一小块内存,称为本地分配缓存(TLAB : Thread Local Allocation Buffer)。
分配内存时,只需要在自己的分配缓存中分配即可,由于这个内存区域是线程私有的,所以不会出现并发问题。
可以使用 -XX:+/-UseTLAB 参数来设定 JVM 是否开启 TLAB 。
本文共计1495个文字,预计阅读时间需要6分钟。
创建对象+当JVM+收到一个new+指令时,会检查指令中的参数是否在常量池中存在该符号的引用,还会检查该类是否已经被加载过,如果没有的语句则需要先进行一次类加载。接着就是分配内存。
创建对象
当 JVM 收到一个 new 指令时,会检查指令中的参数在常量池是否有这个符号的引用,还会检查该类是否已经被加载过了,如果没有的话则要进行一次类加载。
接着就是分配内存了,通常有两种方式:
- 指针碰撞
- 空闲列表
使用指针碰撞的前提是堆内存是完全工整的,用过的内存和没用的内存各在一边每次分配的时候只需要将指针向空闲内存一方移动一段和内存大小相等区域即可。
当堆中已经使用的内存和未使用的内存互相交错时,指针碰撞的方式就行不通了,这时就需要采用空闲列表的方式。虚拟机会维护一个空闲的列表,用于记录哪些内存是可以进行分配的,分配时直接从可用内存中直接分配即可。
堆中的内存是否工整是有垃圾收集器来决定的,如果带有压缩功能的垃圾收集器就是采用指针碰撞的方式来进行内存分配的。
分配内存时也会出现并发问题:
这样可以在创建对象的时候使用 CAS 这样的乐观锁来保证。
也可以将内存分配安排在每个线程独有的空间进行,每个线程首先在堆内存中分配一小块内存,称为本地分配缓存(TLAB : Thread Local Allocation Buffer)。
分配内存时,只需要在自己的分配缓存中分配即可,由于这个内存区域是线程私有的,所以不会出现并发问题。
可以使用 -XX:+/-UseTLAB 参数来设定 JVM 是否开启 TLAB 。

