自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

對象的內(nèi)存分配有套路?

存儲 存儲軟件
Java技術(shù)體系中所提倡的自動內(nèi)存管理最終可以歸結(jié)為自動化地解決了兩個(gè)問題:給對象分配內(nèi)存以及回收分配給對象的內(nèi)存。

 前言

Java技術(shù)體系中所提倡的自動內(nèi)存管理最終可以歸結(jié)為自動化地解決了兩個(gè)問題:給對象分配內(nèi)存以及回收分配給對象的內(nèi)存。

回收對象內(nèi)存是垃圾收集器的工作,在上一篇文章中已有闡述,這篇文章主要說一下對象的內(nèi)存分配以及回收策略。

本文大綱:

  •        1、對象優(yōu)先分配在Eden區(qū)
  •        2、大對象直接進(jìn)入老年代
  •        3、長期存活的對象將進(jìn)入老年代
  •        4、動態(tài)對象年齡判定
  •        5、空間分配擔(dān)保
  •        6、總結(jié)

[[219962]]

一、對象優(yōu)先分配在Eden區(qū)

大多數(shù)情況下,對象都是優(yōu)先在Eden區(qū)分配的,當(dāng)Eden區(qū)沒有足夠的空間進(jìn)行分配時(shí),則虛擬機(jī)會進(jìn)行GC回收(Minor GC)。

設(shè)置***堆和初始化堆都為20M,新生代分配10M,打印GC軌跡。

運(yùn)行結(jié)果如下:

可以發(fā)現(xiàn)對象都被分配在Eden區(qū),默認(rèn)的Eden區(qū)與Survivor區(qū)比例是8,所以Eden區(qū)占8/10=8M,Survivor區(qū)有兩個(gè),每個(gè)都是1M。Eden區(qū)使用了56%,即5.6M,程序中對象obj和obj2各占2M,那多出來的1.6M是哪里來的?

原因是程序中的對象被存儲時(shí)會被轉(zhuǎn)換為虛擬機(jī)對象,而虛擬機(jī)對象包括對象頭、對象的實(shí)例數(shù)據(jù)以及對齊填充。對象的實(shí)例數(shù)據(jù)可以理解為我們程序中分配的2M,多出來的1.6M自然就是對象頭和對齊填充搞的事。

二、大對象直接進(jìn)入老年代

大對象會被分配進(jìn)老年代,可以通過虛擬機(jī)參數(shù)PretenureSizeThreshold來指定多大才算大對象。

設(shè)置***堆和初始化堆都為20M,新生代分配10M,打印GC軌跡,3M視為大對象。

運(yùn)行結(jié)果如下,可以發(fā)現(xiàn)6M的對象被分配到了老年代(tenured generation)中。

三、長期存活的對象將進(jìn)入老年代

長期存活的對象也會被晉升到老年代中,默認(rèn)是15次的Minor GC年齡。意思就是一個(gè)對象在新生代中發(fā)生了15次的GC之后,如果還存活就會晉升為老年代對象。

這個(gè)年齡可以通過虛擬機(jī)參數(shù)MaxTenuringThreshold進(jìn)行配置。

設(shè)置MaxTenuringThreshold=0即意味著只要新生代發(fā)現(xiàn)GC馬上晉升為老年代對象。

運(yùn)行結(jié)果如下,發(fā)現(xiàn)在***次GC的時(shí)候,對象obj和obj2都進(jìn)入了老年代。

設(shè)置MaxTenuringThreshold=3即意味著要經(jīng)過三次GC才可以晉升為老年代對象。

運(yùn)行結(jié)果如下,發(fā)現(xiàn)這次只有obj2進(jìn)入了老年代,對象obj2是因?yàn)樘笤赟urvivor區(qū)存不下才進(jìn)入老年代的。毫無懸念,對象obj留在了Survivor區(qū)。Eden存的是對象obj3。

四、動態(tài)對象年齡判定

為了更好地適應(yīng)不同程序的內(nèi)存狀況,虛擬機(jī)并不是永遠(yuǎn)要求對象的年齡必須達(dá)到了MaxTenuringThreshold才能晉升老年代,如果在Survivor空間中相同年齡所有對象的大小的總和大于Survivor空間的一半,年齡大于或等于該年齡的對象就可以直接進(jìn)入老年代。

首先為對象obj、obj2各分配256K內(nèi)存,他們之和大于512K(因?yàn)樘摂M機(jī)對象還包含對象頭,所以是大于,不是等于),即大于Survivor的一半,所以會晉升為老年代。

運(yùn)行結(jié)果如下,可以發(fā)現(xiàn)對象obj、obj2、obj3都進(jìn)入老年代。對象obj3是因?yàn)樘骃urvivor存不下而進(jìn)入老年代的。

為了更好的體驗(yàn)動態(tài)年齡的效果,作一個(gè)對比,這次設(shè)置為對象obj、obj2各分配128K內(nèi)存,他們之和小于512K,即小于Survivor的一半,所以不會晉升為老年代。

運(yùn)行結(jié)果如下,可以發(fā)現(xiàn)對象obj、obj2被存儲于survivor區(qū)了。老年代存儲的是對象obj3,Eden區(qū)存儲的是***壓入內(nèi)存的obj4對象。

五、空間分配擔(dān)保

在發(fā)生MinorGC之前,虛擬機(jī)會先檢查老年代***可用的連續(xù)空間是否大于新生代所有對象的總空間,如果這個(gè)條件成立,即大于,那么MinorGC可以確保是安全的。當(dāng)不大于時(shí)會有空間分配擔(dān)保一說法。

空間分配擔(dān)保是指上面的條件不成立時(shí),如果允許空間分配擔(dān)保,則虛擬機(jī)會進(jìn)行一次MinorGC,而不是Full GC,盡管有可能內(nèi)存溢出。如果不允許空間分配擔(dān)保,則會進(jìn)行一次FullGC,那停頓的時(shí)間就相對長很多了。一般FullGC的停頓時(shí)間是Minor GC的十倍。補(bǔ)充一點(diǎn),是否允許空間分配擔(dān)??梢酝ㄟ^虛擬機(jī)參數(shù)HandlePromotionFailure配置。

簡而言之,投資總有風(fēng)險(xiǎn),只不過空間分配擔(dān)保的回報(bào)率很高,可以減少停頓時(shí)間,提高應(yīng)用程序的效應(yīng)速度。

 

責(zé)任編輯:武曉燕 來源: Java框架源碼分析
相關(guān)推薦

2018-04-08 08:45:53

對象內(nèi)存策略

2015-11-16 11:22:05

Java對象內(nèi)存分配

2022-10-24 14:12:59

PyTorch內(nèi)存工具

2013-11-07 09:42:42

對象對象池加速

2021-03-22 11:51:22

Java內(nèi)存棧上

2021-02-28 13:22:54

Java內(nèi)存代碼

2023-03-26 00:43:42

JVM對象測試

2021-12-16 06:52:33

C語言內(nèi)存分配

2010-09-25 15:40:52

配置JVM內(nèi)存

2019-07-29 10:10:06

Java內(nèi)存線程安全

2021-07-30 07:22:51

JVM虛擬機(jī)棧 Stack

2024-08-05 09:05:44

2021-07-14 10:00:32

Python內(nèi)存測量

2018-05-15 16:01:53

對象內(nèi)存JVM

2009-06-03 15:52:34

堆內(nèi)存棧內(nèi)存Java內(nèi)存分配

2010-09-25 14:12:50

Java內(nèi)存分配

2024-01-05 09:23:09

Linux系統(tǒng)內(nèi)存內(nèi)存指標(biāo)

2022-03-16 08:39:19

StackHeap內(nèi)存

2019-09-10 16:25:19

Python內(nèi)存空對象

2020-10-21 09:28:25

JS變量的內(nèi)存分配
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號