更新時間:2020-06-01 15:46:10 來源:動力節(jié)點 瀏覽1854次
java程序會發(fā)生內(nèi)存泄露的問題嗎?請簡單說說你的觀點
答案:會。Java內(nèi)存管理是通過垃圾收集器(Garbage Collection,GC)自動管理內(nèi)存的回收的,java程序員不需要通過調(diào)用函數(shù)來釋放內(nèi)存。因此,很多人錯誤地認(rèn)為Java不存在內(nèi)存泄漏問題,或者認(rèn)為即使有內(nèi)存泄漏也不是程序的責(zé)任,而是GC或JVM的問題。其實Java也存在內(nèi)存泄露,但它的表現(xiàn)與C++語言有些不同。
java導(dǎo)致內(nèi)存泄露的原因很明確:長生命周期的對象持有短生命周期對象的引用就很可能發(fā)生內(nèi)存泄露,盡管短生命周期對象已經(jīng)不再需要,但是因為長生命周期對象持有它的引用而導(dǎo)致不能被回收。
嚴(yán)格來說,內(nèi)存泄漏就是存在一些被分配的對象,這些對象有下面兩個特點,首先,這些對象是可達的,即在有向圖中,存在通路可以與其相連;其次,這些對象是無用的,即程序以后不會再使用這些對象。如果對象滿足這兩個條件,這些對象就可以判定為Java中的內(nèi)存泄漏,這些對象不會被GC所回收,然而它卻占用內(nèi)存。
在java程序中容易發(fā)生內(nèi)存泄露的場景:
1.集合類,集合類僅僅有添加元素的方法,而沒有相應(yīng)的刪除機制,導(dǎo)致內(nèi)存被占用。這一點其實也不明確,這個集合類如果僅僅是局部變量,根本不會造成內(nèi)存泄露,在方法棧退出后就沒有引用了會被jvm正常回收。而如果這個集合類是全局性的變量(比如類中的靜態(tài)屬性,全局性的map等即有靜態(tài)引用或final一直指向它),那么沒有相應(yīng)的刪除機制,很可能導(dǎo)致集合所占用的內(nèi)存只增不減,因此提供這樣的刪除機制或者定期清除策略非常必要。
2.單例模式。不正確使用單例模式是引起內(nèi)存泄露的一個常見問題,單例對象在被初始化后將在JVM的整個生命周期中存在(以靜態(tài)變量的方式),如果單例對象持有外部對象的引用,那么這個外部對象將不能被jvm正常回收,導(dǎo)致內(nèi)存泄露,考慮下面的例子:
class A{
public A(){
B.getInstance().setA(this);
}
….
}
//B類采用單例模式
class B{
private A a;
private static B instance=new B();
public B(){}
public static B getInstance(){
return instance;
}
public void setA(A a){
this.a=a;
}
//getter…
}
顯然B采用singleton模式,他持有一個A對象的引用,而這個A類的對象將不能被回收。想象下如果A是個比較大的對象或者集合類型會發(fā)生什么情況。
所以在Java開發(fā)過程中和代碼復(fù)審的時候要重點關(guān)注那些長生命周期對象:全局性的集合、單例模式的使用、類的static變量等等。在不使用某對象時,顯式地將此對象賦空,遵循誰創(chuàng)建誰釋放的原則,減少內(nèi)向泄漏發(fā)生的機會。
以上就是動力節(jié)點java培訓(xùn)機構(gòu)的小編針對“常出現(xiàn)錯誤的兩道高級java工程師筆試題”的內(nèi)容進行的回答,希望對大家有所幫助,如有疑問,請在線咨詢,有專業(yè)老師隨時為你服務(wù)。
相關(guān)閱讀
0基礎(chǔ) 0學(xué)費 15天面授
有基礎(chǔ) 直達就業(yè)
業(yè)余時間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請后,顧問老師會電話與您溝通安排學(xué)習(xí)