作者:牛涛fd_501 | 来源:互联网 | 2024-11-18 13:36
本文由编程笔记#小编为大家整理,主要介绍了JVM内存分配相关的知识,希望对你有一定的参考价值。
## 内存规整
堆中的内存空间是否规整(连续的),取决于JVM垃圾收集器所采用的垃圾回收算法。如果垃圾回收算法包含压缩算法,如Serial或Parallel Scavenge收集器,则内存空间是连续的、规整的。而如果垃圾回收算法是标记-清除算法,如CMS收集器,则内存空间是不连续的、不规整的。内存空间的规整与否直接影响了内存的分配方式。
## 内存分配方式
### 指针碰撞
当内存空间规整且连续时,JVM采用指针碰撞法进行内存分配。在这种方式下,堆内存被分为已分配和未分配两个部分,中间有一个指针。每次分配新对象实例时,只需将指针向前移动相应的大小即可。这种方式简单高效,但前提是内存必须是规整的。
### 空闲列表
当内存空间不规整且不连续时,JVM采用空闲列表法进行内存分配。在这种方式下,JVM会维护一个空闲内存块的列表,每次分配新对象实例时,从列表中找到一个足够大的空闲块并分配给对象实例。这种方式适用于内存碎片较多的情况,但查找空闲块的过程可能会增加开销。
## 并发指针碰撞问题
在同一块内存区域执行指针碰撞时,可能会出现并发问题。为了解决这一问题,JVM提供了以下两种方法:
1. **同步加锁**:对分配内存空间的动作进行同步加锁处理,确保同一时间只有一个线程能够执行内存分配操作。这种方法虽然简单,但会引入额外的锁开销,影响性能。
2. **本地线程分配缓冲(TLAB)**:为每个线程在堆中预先分配一小块内存TLAB,线程在各自的TLAB上为自己的实例对象分配内存空间。当TLAB使用完时,再进行同步加锁,分配新的TLAB。这种方法减少了全局锁的竞争,提高了并发性能。
### TLAB
TLAB(Thread Local Allocation Buffer)是一种用于减少多线程环境下内存分配竞争的技术。每个线程都有一个独立的TLAB,线程在自己的TLAB上分配内存,避免了多线程间的同步开销。当一个线程的TLAB用尽时,会请求新的TLAB。TLAB的大小可以通过JVM参数进行调整,以适应不同的应用场景。