国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

內(nèi)存溢出與內(nèi)存泄漏

2019-11-09 17:06:00
字體:
供稿:網(wǎng)友

什么是內(nèi)存溢出?

簡單點說,當(dāng)一個對象不再被使用(即失去了利用價值),但它的引用卻依然被其他對象所持有,導(dǎo)致JVM的垃圾回收機制無法回收釋放此對象,則該無用對象繼續(xù)占用內(nèi)存空間(占著茅坑。。。),即內(nèi)存泄漏了。所有內(nèi)存都被占用且無法進(jìn)行垃圾回收時,就會發(fā)生內(nèi)存溢出。

全面點說,那要從java虛擬機運行時的數(shù)據(jù)區(qū)域說起,《深入理解java虛擬機:JVM高級特性與最佳實踐》這本書對此闡釋很明確,jvm所管理的內(nèi)存將會包括以下幾個運行時的數(shù)據(jù)區(qū)域:

這里寫圖片描述

這幾個數(shù)據(jù)區(qū)除程序計數(shù)器外都會發(fā)生內(nèi)存溢出問題(內(nèi)存泄露的后果是內(nèi)存溢出,但內(nèi)存溢出并不都是有內(nèi)存泄露引起的)。

一、程序計數(shù)器

程序計數(shù)器是一塊較小的內(nèi)存空間,它可以看作是當(dāng)前線程執(zhí)行字節(jié)碼的行號指示器,在虛擬機的概念模型里,字節(jié)碼解釋器的工作就是通過改變程序計數(shù)器的值來選去下一條執(zhí)行的字節(jié)碼指令,分之,循環(huán),跳轉(zhuǎn),異常處理,線程恢復(fù)等基礎(chǔ)功能都需要依賴這個程序計數(shù)器來完成。每條線程都持有一個獨立的程序計數(shù)器,各個計數(shù)器之間互不影響?yīng)毩⒋鎯Γ@類內(nèi)存區(qū)域被稱為“線程私有”內(nèi)存。 如果執(zhí)行java指令,此計數(shù)器中存有當(dāng)前執(zhí)行的字節(jié)碼指令的行數(shù),若執(zhí)行native方法,則這個計數(shù)器的值為空(Undefined)。此內(nèi)存區(qū)域是唯一一個jvm規(guī)范沒有規(guī)定OutOfMemoryError的區(qū)域。

二、虛擬機棧

虛擬機棧也是一塊兒線程私有內(nèi)存,它描述的是java方法執(zhí)行的內(nèi)存模型:每個方法在執(zhí)行的時候會創(chuàng)建一個幀棧,這個幀棧用于存儲局部變量表、操作數(shù)棧、動態(tài)鏈接、方法出口等信息,每一個方法調(diào)用到執(zhí)行完的過程就是幀棧從虛擬機棧入棧到出棧的過程。我們常說的“堆棧”中的棧就是指虛擬機棧,更精確的說是指虛擬機棧中存儲的局部變量表。局部變量表中存儲了編譯期可知的基本數(shù)類型,對象的引用,以及returnAddress類型——指向一條字節(jié)碼指令的地址。(long和double占兩個Slot——局部變量空間,其他類型占一個Slot) 當(dāng)進(jìn)入一個方法是,該方法對應(yīng)的局部變量空間是確定了的,并且在方法執(zhí)行期間不會改變。在jvm規(guī)范中,對這個區(qū)域規(guī)定了兩種異常狀況:如果請求的棧深度大于虛擬機所允許的最大深度,會拋出StackOverflowError;如果虛擬機可以動態(tài)擴展,并且在擴展時無法申請到足夠內(nèi)存,則或拋出OutOfMemoryError。

三、本地方法棧

本地方法棧同虛擬機棧功能類似,都是為了執(zhí)行方法而服務(wù)的,只不過本地方法棧是服務(wù)于Native方法,jvm并沒有對此區(qū)域做具體的規(guī)定,同虛擬機棧一樣本地方法棧也會拋出上文兩個異常。

四、java堆

java堆我們很熟悉了,它是虛擬機管理的內(nèi)存區(qū)域中最大的一塊,被所有線程所共享,在虛擬機啟動時被創(chuàng)建。堆存在的唯一目的是存儲對象的實例,但隨著技術(shù)的發(fā)展,堆的作用也不是那么“絕對”了。堆也是垃圾收集器管理的主要區(qū)域,jvm規(guī)范規(guī)定堆可以處于物理上不連續(xù)的內(nèi)存空間中,只要邏輯上連續(xù)即可。堆的大小可以是固定的,也可以是擴展的,如果在堆中沒有完成實例分配,并且堆也無法在擴展時,將會拋出OutOfMemoryError異常。

五、方法區(qū)

方法區(qū)也是一塊被線程共享的區(qū)域,它用于存儲已經(jīng)被虛擬機掛在的類信息、常量、靜態(tài)變量、即時編譯器編譯后的代碼等數(shù)據(jù),雖然Jvm規(guī)范把方法區(qū)描述為堆的一個邏輯部分,但他卻有一個別名叫做Non-Heap(非堆),目的應(yīng)該是與java堆區(qū)分開來。jvm對方法區(qū)的規(guī)范較為寬松,也可以不實現(xiàn)垃圾收集,當(dāng)方法區(qū)無法滿足內(nèi)存分配需求時,會拋出OutOfMemoryError異常。

六、運行時常量池

運行時常量池是方法區(qū)的一部分,用于存放編譯期生成的各種字面量和符號引用,這部分內(nèi)容將在類加載后進(jìn)入方法區(qū)時存放。它同時受到方法區(qū)內(nèi)存的限制,當(dāng)其無法申請內(nèi)存時會拋出OutOfMemoryError異常。

七、直接內(nèi)存

直接內(nèi)存并不是虛擬機運行時數(shù)據(jù)區(qū)的一部分,但這部分內(nèi)存也會被頻繁的使用,當(dāng)jvm動態(tài)擴展時各區(qū)域總內(nèi)存超過了物理內(nèi)存限制,也會拋出OutOfMemoryError異常。

Android中的內(nèi)存泄漏

在Android開發(fā)中我們主要關(guān)心的是java堆中的內(nèi)存泄漏問題,Android中常見的內(nèi)存泄漏有一下幾個地方: 資源使用完畢沒有關(guān)閉:數(shù)據(jù)庫cursor,流等 靜態(tài)變量、單例持有對象的引用會使該對象無法銷毀 無限循環(huán)的屬性動畫也會使activity無法銷毀 context被生命周期常于activity的對象持有導(dǎo)致activity無法銷毀 集合類持有無用對象的引用 匿名內(nèi)部類或非靜態(tài)內(nèi)部類實例會持有外部類的引用,導(dǎo)致無法回收 handler引用被MessageQueue持有直到消息被送達(dá)


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 凭祥市| 丹东市| 苏州市| 阿城市| 邹平县| 新绛县| 谢通门县| 夏河县| 津南区| 莱西市| 田东县| 翁源县| 邹平县| 双鸭山市| 孙吴县| 翼城县| 秦安县| 凤山县| 浮山县| 洪江市| 林甸县| 抚宁县| 贵港市| 印江| 天长市| 钟山县| 孝感市| 霍城县| 乌审旗| 秭归县| 萍乡市| 合肥市| 肇州县| 红河县| 蓝山县| 莫力| 泰顺县| 盐亭县| 大兴区| 崇仁县| 丰都县|