Java:如何避免Java內存泄漏
Java的核心優(yōu)勢之一就是利用JVM(Java虛擬機),JVM是一種開(kāi)箱即用的內存管理。你只管創(chuàng )建對象,Java的垃圾回收器幫你分配以及回收內存。然而,實(shí)際的情況并沒(méi)有那么簡(jiǎn)單,因為內存泄漏在Java應用程序中還是時(shí)有發(fā)生的。
為了避免內存泄漏,你需要注意如何編寫(xiě)代碼。以下是幫助你消除內存泄漏的具體方法。
1.使用引用對象避免內存泄漏
JavaWorld的RaimondRichert寫(xiě)道,你可以使用引用對象來(lái)消除內存泄漏。
使用java.lang.ref包,可以在程序中使用垃圾收集器。這允許你避免直接引用對象,并使用垃圾收集器容易清除的特殊引用對象。特殊的子類(lèi)允許你間接引用對象。例如,Reference有三個(gè)子類(lèi):PhantomReference、SoftReference和WeakReference。
可以使用引用對象的get方法訪(fǎng)問(wèn)引用對象或這些子類(lèi)引用的對象。使用此方法的優(yōu)點(diǎn)是,通過(guò)將引用設置為null,可以輕松地清除引用,并且引用幾乎是不可變的。垃圾收集器如何處理每種類(lèi)型的引用?
l SoftReference對象:當內存不足時(shí),需要垃圾收集器清除所有SoftReference對象。
l WeakReference對象:當垃圾收集器檢測到弱引用對象時(shí),對它的所有引用都將被清除,并最終從內存中取出。
l PhantomReference對象:垃圾收集器無(wú)法自動(dòng)清理PhantomReference對象,因此只能手動(dòng)清理所有PhantomReferences對象和引用。
使用引用對象,可以使用垃圾收集器自動(dòng)執行刪除弱可訪(fǎng)問(wèn)偵聽(tīng)器的任務(wù)。WeakReference對象,尤其是清理線(xiàn)程,可以幫助你避免內存錯誤。
2.避免與WebApp類(lèi)加載器相關(guān)的內存泄漏
使用碼頭7.6.6?;蚋甙姹?,你可以防止WebApp類(lèi)加載器固定。當代碼不斷引用WebApp類(lèi)加載器時(shí),內存泄漏很容易發(fā)生。在這種情況下有兩種類(lèi)型的泄漏:守護進(jìn)程線(xiàn)程和靜態(tài)字段。
靜態(tài)字段以類(lèi)加載器的值開(kāi)始。即使Jetty停止部署并重新部署web應用程序,靜態(tài)引用仍然存在,因此無(wú)法從內存中清除對象。
在web應用程序生命周期之外啟動(dòng)的守護程序線(xiàn)程,由于這些線(xiàn)程引用了啟動(dòng)線(xiàn)程的類(lèi)加載器,因此容易發(fā)生內存泄漏。
使用Jetty,你可以使用預防器來(lái)幫助你解決與WebApp類(lèi)加載器相關(guān)的問(wèn)題。例如,appcontext.getappcontext()等應用程序上下文泄漏防止器可以幫助你將靜態(tài)引用保存在上下文類(lèi)加載器中。在Java培訓中,有更加系統全面的課程,明確清晰的學(xué)習路線(xiàn),學(xué)習起來(lái)既輕松,又高效。
你可以使用的其他防護裝置包括:
AWT防泄漏器
DOM防泄漏器
駕駛員經(jīng)理防泄漏器
GC螺紋防泄漏器
Java2D防泄漏器
LDAP防泄漏器
登錄配置防泄漏器
安全提供商防泄漏器
3.其他具體步驟
還有幾種防止Java內存泄漏的方法,包括:
l 不再需要時(shí),釋放會(huì )話(huà)。使用()執行此操作。
l 保持每個(gè)會(huì )話(huà)的超時(shí)時(shí)間較低。
l 在中只存儲必要的數據。
l 避免使用字符串串聯(lián)。使用StringBuffer的append()方法,因為字符串是不可更改的對象,而字符串串聯(lián)會(huì )創(chuàng )建許多不必要的對象。大量臨時(shí)對象會(huì )降低性能。
l 盡可能不要在jsp頁(yè)面上創(chuàng )建”%來(lái)執行此操作。
l 如果要編寫(xiě)頻繁執行的查詢(xún),請使用PreparedStatement對象,而不是使用Statement對象。為什么?PreparedStatement是預編譯的,而每次將SQL語(yǔ)句傳輸到數據庫時(shí)都會(huì )編譯Statement。
l 使用JDBC代碼時(shí),在編寫(xiě)查詢(xún)時(shí)避免使用“*”。請嘗試改用相應的列名。
l 如果要在循環(huán)中使用stmt=con.prepareStatement(SQL query ),請確保在特定循環(huán)中關(guān)閉它。
l 當需要重用語(yǔ)句和結果集時(shí),請務(wù)必關(guān)閉它們。
l 關(guān)閉最終塊中的ResultSet、Connection、PreparedStatement和Statement。
總結
Java 中的內存泄漏被認為是一種疾病,因為它們會(huì )阻礙資源的性能。如果他們不能及時(shí)修復或避免,隨著(zhù)時(shí)間的推移,可能會(huì )導致致命的應用程序崩潰。