摘要:集合中的內存泄漏,比如等,這些對象經常會發生內存泄露。目前,我們通常使用一些工具來檢查程序的內存泄漏問題。開發人員將根據這些信息判斷程序是否有內存泄漏問題。
01. 怎么回事?納尼,Java 不是自動管理內存嗎?怎么可能會出現內存泄泄泄泄泄泄漏!
Java 最牛逼的一個特性就是垃圾回收機制,不用像 C++ 需要手動管理內存,所以作為 Java 程序員很幸福,只管 New New New 即可,反正 Java 會自動回收過期的對象。。。
那么 Java 都自動管理內存了,那怎么會出現內存泄漏,難道 Jvm 有 bug"); 02. 怎么判斷可以被回收
先了解一下 Jvm 是怎么判斷一個對象可以被回收。一般有兩種方式,一種是引用計數法,一種是可達性分析。
引用計數法:每個對象有一個引用計數屬性,新增一個引用時計數加1,引用釋放時計數減1,計數為0時可以回收。
這個辦法看起來挺簡單的,但是如果出現 A 引用了 B,B 又引用了 A,這時候就算他們都不再使用了,但因為相互引用 計算器=1 永遠無法被回收。
此方法簡單,無法解決對象相互循環引用的問題。
可達性分析(Reachability Analysis):從 GC Roots 開始向下搜索,搜索所走過的路徑稱為引用鏈。當一個對象到 GC Roots 沒有任何引用鏈相連時,則證明此對象是不可用的,那么虛擬機就判斷是可回收對象。
可達性分析可以解決循環引用的問題。
那么 gc roots 對象是哪些呢
虛擬機棧中引用的對象
方法區中類靜態屬性引用的對象
方法區中常量引用的對象
本地方法棧中JNI[即一般說的Native]引用的對象
目前主流的虛擬機中大多使用可達性分析的方式來判定對象是否可被 GC 回收。
03. 什么情況下會出現內存泄漏既然可達性分析好像已經很牛逼的樣子了,怎么可能還會出現內存泄漏呢,那我們再來看一下內存泄漏的定義。
內存泄露就是指一個不再被程序使用的對象或變量一直被占據在內存中。
有可能此對象已經不使用了,但是還有其它對象保持著此對象的引用,就會導致 GC 不能回收此對象,這種情況下就會出現內存泄漏。
寫一個程序讓出現內存泄漏
①長生命周期的對象持有短生命周期對象的引用就很可能發生內存泄露,盡管短生命周期對象已經不再需要,但是因為長生命周期對象持有它的引用而導致不能被回收。
public class Simple {
Object object;
public void method1(){
object = new Object();
//...其他代碼
}
}
這里的 object 實例,其實我們期望它只作用于 method1() 方法中,且其他地方不會再用到它,但是,當method1()方法執行完成后,object 對象所分配的內存不會馬上被認為是可以被釋放的對象,只有在 Simple 類創建的對象被釋放后才會被釋放,嚴格的說,這就是一種內存泄露。
解決方法就是將 object 作為 method1() 方法中的局部變量。
public class Simple {
Object object;
public void method1(){
object = new Object();
//...其他代碼
object = null;
}
}
當然大家有可能會想就這一個方法也不會有多大影響,但如果在某些項目中,一個方法在一分鐘之內調用上萬次的時候,就會出現很明顯的內存泄漏現象。
②集合中的內存泄漏,比如 HashMap、ArrayList 等,這些對象經常會發生內存泄露。比如當它們被聲明為靜態對象時,它們的生命周期會跟應用程序的生命周期一樣長,很容易造成內存不足。
下面給出了一個關于集合內存泄露的例子。
Vector v=new Vector(10);
for (int i=1;i<100; i++)
{
Object o=new Object();
v.add(o);
o=null;
}
//此時,所有的Object對象都沒有被釋放,因為變量v引用這些對象。
在這個例子中,我們循環申請 Object 對象,并將所申請的對象放入一個 Vector 中,如果我們僅僅釋放引用本身,那么 Vector 仍然引用該對象,所以這個對象對 GC 來說是不可回收的。
因此,如果對象加入到 Vector 后,還必須從 Vector 中刪除,最簡單的方法就是將 Vector 對象設置為 null。
以上兩種是最常見的內存泄漏案例。當然還有一些內存泄漏的例子,這里就不再一一例舉了,感興趣的同學可以在網上找找資料。
04. 內存泄漏和內存溢出很多同學總是搞不清楚,內存泄漏和內存溢出的區別,它倆是兩個完全不同的概念, 它們之間存在一些關聯。
內存溢出 out of memory,是指程序在申請內存時,沒有足夠的內存空間供其使用,出現 out of memory;
內存泄露 memory leak,是指程序在申請內存后,無法釋放已申請的內存空間,一次內存泄露危害可以忽略,但內存泄露堆積后果很嚴重,無論多少內存,遲早會被占光。
所以內存泄漏可能會導致內存溢出,但內存溢出并不完全都是因為內存泄漏,也有可能使用了太多的大對象導致。
05. 如何檢測內存泄漏最后一個重要的問題,就是如何檢測 Java 的內存泄漏。目前,我們通常使用一些工具來檢查 Java 程序的內存泄漏問題。
市場上已有幾種專業檢查 Java 內存泄漏的工具,它們的基本工作原理大同小異,都是通過監測 Java 程序運行時,所有對象的申請、釋放等動作,將內存管理的所有信息進行統計、分析、可視化。開發人員將根據這些信息判斷程序是否有內存泄漏問題。
這些工具包括 Plumbr 、Eclipse Memory Analyzer、JProbe Profiler、JVisualVM 等。
06. 最后以上內容其實是我曾經經常面試的內容之一,通過一系列的問題考察 Java 程序員對 Jvm 的理解。
比如我通常會問面試者,Java 中存在內存泄漏嗎?大部分人都會回答存在,接著我會問如果讓你寫一個程序讓內存泄漏,你會怎么寫?大部分程序員就回答不上來了。
如果面試者可以回答上面的問題,我會接著和面試者聊聊,內存泄漏和內存溢出他們之間是否存在聯系 、以及在日常工作中如何避免寫出內存泄漏的代碼 、如果生產出現 Jvm 相關問題時,排查問題的思路和步驟等等。
這些問題在我的博客中都有答案,早些年寫了一系列關于 Jvm 的文章,大家如果感興趣的話接下來繼續去閱讀,www.ityouknow.com/java.html。
如果大家覺得在手機上看著更方便,可以關注:Java 極客技術公號,已經輸出了一些 JVM 文章,我博客中的 Jvm 系列文章也都會推送到這個公號中。
關注一下又不會懷孕
參考出處:
lovoedu.gitee.io/javablog/20…
www.ibm.com/developerwo…
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/7185.html
摘要:垃圾回收所謂垃圾就是指通過循環引用自己引用自己,目前只在類型中有出現的形式而導致永遠不為。當出現垃圾之后,的引擎有對應的垃圾回收機制。觸發這個機制的時機是每次出現減少時候。 自嘲)。。。。。2333,我覺得這是因為在php語言層面就幫我們解決了內存回收的問題,但這讓我在和java大牛們吹牛逼的時候,聽到什么內存泄露。。。。(納尼,我tmd怎么從來沒遇見過)一臉懵逼。 本人小菜,如果下面...
摘要:納尼隔壁少林派表示自家金剛技壓群雄在座各位都是。。。納尼你覺得寫太繁瑣了你不喜歡我們還有或者等等一大堆工具呢。納尼沒有你還是覺得無法接受好吧那么筆者推薦類似這類更友好的工具你可以導入導出其他格式也可以使用其來撰寫。 說起微服務, 想必現在的技術圈內人士個個都能談笑風云, 娓娓道來。的確, 技術變革日新月異, 各種工具框架雨后春筍般涌現, 現在我們可以輕巧便捷地根據自己的業務需求, 構建...
摘要:本系列文章會記錄阿里云容器服務團隊在支持客戶中的一些心得體會和最佳實踐。阿里云服務全球首批通過一致性認證,簡化了集群生命周期管理,內置了與阿里云產品集成,也將進一步簡化的開發者體驗,幫助用戶關注云端應用價值創新。 showImg(https://segmentfault.com/img/bV6FTH?w=740&h=296); 隨著容器技術的成熟,越來越多的企業客戶在企業中選擇Dock...
摘要:本系列文章會記錄阿里云容器服務團隊在支持客戶中的一些心得體會和最佳實踐。阿里云服務全球首批通過一致性認證,簡化了集群生命周期管理,內置了與阿里云產品集成,也將進一步簡化的開發者體驗,幫助用戶關注云端應用價值創新。 showImg(https://segmentfault.com/img/bV6FTH?w=740&h=296); 隨著容器技術的成熟,越來越多的企業客戶在企業中選擇Dock...
摘要:強大的表單驗證前端掘金支持非常強大的內置表單驗證,以及。面向對象和面向過程的區別的種設計模式全解析后端掘金一設計模式的分類總體來說設計模式分為三大類創建型模式,共五種工廠方法模式抽象工廠模式單例模式建造者模式原型模式。 強大的 Angular 表單驗證 - 前端 - 掘金Angular 支持非常強大的內置表單驗證,maxlength、minlength、required 以及 patt...
閱讀 2076·2021-11-11 16:55
閱讀 1413·2021-09-28 09:36
閱讀 1053·2019-08-29 15:21
閱讀 1585·2019-08-29 14:10
閱讀 2767·2019-08-29 14:08
閱讀 1643·2019-08-29 12:31
閱讀 3254·2019-08-29 12:31
閱讀 987·2019-08-26 16:47