虛擬機(jī)進(jìn)行new對(duì)象指令時(shí)是先分辨是否能引用,然后判斷是否加載(類加載),接著就是分配內(nèi)存,如果gc帶有壓縮整理功能,則分配方式為空閑列表(CMS基于Mark-Sweep算法收集器),如果不帶,就是用指針碰撞的方式分配,Serial,ParNew帶Compact的收集器這類的
對(duì)象的創(chuàng)建在虛擬機(jī)中是如何保證安全的
1:同步(類似于加鎖)2:分配不同的創(chuàng)建區(qū)域(把兩者想分配在不同區(qū)域,自然就不會(huì)有沖突的情況)
如何使用對(duì)象
1:句柄訪問,在棧中有一個(gè)reference,存的是句柄池句柄的地址,句柄則包含了所有對(duì)象的數(shù)據(jù)類型和類型數(shù)據(jù)各自的地址,好處:在復(fù)制清除中,只需要修改reference的值,就可以,不需要移動(dòng)太多的數(shù)據(jù)
2:直接指針訪問:reference存的是對(duì)象的地址,好處:速度快,減少開銷
各個(gè)位置內(nèi)存溢出的原因
堆溢出:不斷創(chuàng)建新對(duì)象,并保證gc到達(dá)對(duì)象之間有可達(dá)路徑避免被清除.對(duì)象數(shù)量大于最大容量就會(huì)oom
解決辦法:確認(rèn)內(nèi)存中的對(duì)象是否必須存在:
虛擬機(jī)棧溢出和本地方法棧溢出
1:線程請(qǐng)求的棧深度大于虛擬機(jī)所允許的最大深度,拋出StackOverFlowError
2:虛擬機(jī)在擴(kuò)展棧時(shí),沒有足夠的內(nèi)存空間,拋出OutOfMemoryError
解決辦法:減少單個(gè)線程的內(nèi)存,減少最大堆和最小的棧容量來換取更多的線程(單個(gè)線程的內(nèi)存越大,越有可能出現(xiàn)內(nèi)存溢出的情況,在多線程的情況下,減少單個(gè)線程的內(nèi)存大小,可以盡量避免出現(xiàn)棧溢出的錯(cuò)誤)
方法區(qū)和運(yùn)行時(shí)常量池溢出:
原因:運(yùn)行時(shí)產(chǎn)生大量的類填滿方法區(qū),
常見的:大量jsp或產(chǎn)生jsp文件的應(yīng)用,jsp第一次運(yùn)行會(huì)編譯成java類,同個(gè)類被不同加載器加載,會(huì)被視為不同的類CGlib動(dòng)態(tài)生成的class
本機(jī)直接內(nèi)存溢出
沒有申請(qǐng)分配內(nèi)存,卻通過其他方式來獲取實(shí)例進(jìn)行內(nèi)存分配(想要內(nèi)存,卻沒申請(qǐng))