- 简介
- 怎么分配
- 指针碰撞
- 空闲列表
- 并发分配
- CAS
- 线程本地分配缓存区(TLAB;Thread Local Allocation Buffer)
当我们使用new关键字创建一个类的对象时,首先先去检查当前类是否已经被加载过,如果没有被加载,那么会先执行当前类的类加载;在通过类加载的检查后,接下来就该为这个对象去分配内存,对象所需内存的大小在类加载完成后就可以确定;为对象分配内存的任务等同于把一块确定大小的内存从JVM堆中划分出来.这个时候引出来两个问题:怎么分配和并发分配
怎么分配分配内存两种方法:指针碰撞(默认)和空闲列表
指针碰撞- 如果Java堆中内存是绝对规整的,用过的内存放在一边,没有使用过的内存放在另一边,中间用一个指针来作为两块区域的分界点;那么分配内存就仅仅是把那个指针向没有使用过的那一边挪动一段与要分配的对象大小相等的距离
- 如果Java堆中内存不是绝对规整的,用过的内存与没有用过的内存相互交叉.在这种情况下就不能使用指针碰撞方式来进行分配内存了,JVM就必须维护一个列表,记录那些内存块是可用的,那么分配内存时就从列表中找到一块足够大的空间分给要分配的对象;并更新列表
在并发情况下,可能会出现正在给对象A分配内存,指针还没来得及移动,对象B又使用了旧指针来分配内存的情况.
CASJVM采用CAS失败重试的方式保证更新操作的原子性对分配内存的操作进行同步处理
线程本地分配缓存区(TLAB;Thread Local Allocation Buffer)把内存分配的操作按照线程划分在不同的空间之中进行,即每个线程在Java堆中先分配一小块内存,通过 -XX:+UseTLAB参数设置JVM开启TLAB(默认开启;关闭TLAB使用 -XX:+UseTLAB);使用 -XX:TLABSize 指定TLAB大小。



