JVM中对象如何在堆内存分配
在單線程的情況下
1、指針碰撞(Bump The Pointer):內存規整的情況下;
分配空間的工作只是將指針像空閑內存一側移動對象大小的距離即可。
2、空閑列表(Free List):內存不規整的情況下;
這種適用于內存非規整的情況,這種情況下JVM會維護一個內存列表,記錄哪些內存區域是空閑的,大小是多少。給對象分配空間的時候去空閑列表里查詢到合適的區域然后進行分配即可。
選擇哪種分配方式由Java堆是否規整決定,而Java堆是否規整又由所采用的垃圾收集器是否帶有空間壓縮整理(Compact)的能力決定;
因此,當使用Serial、ParNew等帶壓縮整理過程的收集器時,系統采用的分配算法是指針碰撞,既簡單又高效;
而當使用CMS這種基于清除(Sweep)算法的收集器時,理論上就只能采用較為復雜的空閑列表來分配內存;
多線程
對象創建在虛擬機中頻繁發生,即使僅僅修改一個指針所指向的位置,在并發情況下也并不是線程安全的,可能出現正在給對象A分配內存,指針還沒來得及修改,對象B又同時使用了原來的指針來分配內存的情況;
那么解決方案有兩種:
(1)同步鎖定,JVM是采用CAS配上失敗重試的方式保證更新操作的原子性;
(2)線程隔離,把內存分配的動作按照線程劃分在不同的空間之中進行,即每個線程在Java堆中預先分配一小塊內存,稱為本地線程分配緩沖(Thread Local Allocation Buffer,TLAB),哪個線程要分配內存,就在哪個線程的本地緩沖區中分配,只有本地緩沖區用完了,分配新的緩存區時才需要同步鎖定,虛擬機是否使用TLAB,可以通過-XX:+/-UseTLAB參數來設定;
-XX:TLABSize=512k 設置大小;
總結
以上是生活随笔為你收集整理的JVM中对象如何在堆内存分配的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: redis基础命令
- 下一篇: 为什么不要使用finalize方法