0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Java內(nèi)部類使用不當(dāng)導(dǎo)致的內(nèi)存泄露問題及解決辦法

Android編程精選 ? 來源:CSDN ? 2023-05-18 16:09 ? 次閱讀

「說明」

本文介紹 Java 內(nèi)部類持有外部類導(dǎo)致內(nèi)存泄露的原因以及其解決方案。

「為什么內(nèi)部類持有外部類會導(dǎo)致內(nèi)存泄露?」

非靜態(tài)內(nèi)部類會持有外部類,如果有地方引用了這個非靜態(tài)內(nèi)部類,會導(dǎo)致外部類也被引用,垃圾回收時無法回收這個外部類(即使外部類已經(jīng)沒有其他地方在使用了)。

「解決方案」

不要讓其他的地方持有這個非靜態(tài)內(nèi)部類的引用,直接在這個非靜態(tài)內(nèi)部類執(zhí)行業(yè)務(wù)。

將非靜態(tài)內(nèi)部類改為靜態(tài)內(nèi)部類。內(nèi)部類改為靜態(tài)的之后,它所引用的對象或?qū)傩砸脖仨毷庆o態(tài)的,所以靜態(tài)內(nèi)部類無法獲得外部對象的引用,只能從 JVM 的 Method Area(方法區(qū))獲取到static類型的引用。

為什么要持有外部類

Java 語言中,非靜態(tài)內(nèi)部類的主要作用有兩個:

當(dāng)內(nèi)部類只在外部類中使用時,匿名內(nèi)部類可以讓外部不知道它的存在,從而減少了代碼的維護(hù)工作。

當(dāng)內(nèi)部類持有外部類時,它就可以直接使用外部類中的變量了,這樣可以很方便的完成調(diào)用,如下代碼所示:

wKgaomRl3aOAfJj5AAC326t5afA876.jpg

但是,靜態(tài)內(nèi)部類就無法持有外部類和其非靜態(tài)字段了。

比如下邊這樣就會報錯


wKgaomRl3ciAfKSLAAC-XcDhaJ0306.jpg

報錯:

cc479778-e34f-11ed-ab56-dac502259ad0.png

實例:持有外部類

「代碼」


wKgZomRl3eaAC3aAAACaTa8NwN4139.jpg

「斷點調(diào)試」

可以看到:內(nèi)部類持有外部類的對象的引用,是以“this$0”這個字段來保存的。

cc670e96-e34f-11ed-ab56-dac502259ad0.png

實例:不持有外部類

「代碼」

wKgaomRl3hCAKVebAACe3joRVoY043.jpg


「斷點調(diào)試」

可以發(fā)現(xiàn):內(nèi)部類不再持有外部類了。

cc8643b0-e34f-11ed-ab56-dac502259ad0.png

實例:內(nèi)存泄露

「簡介」

若內(nèi)部類持有外部類的引用,對內(nèi)部類的使用很多時,會導(dǎo)致外部類數(shù)目很多。此時,就算是外部類的數(shù)據(jù)沒有被用到,外部類的數(shù)據(jù)所占空間也不會被釋放。 本處在外部類存放大量的數(shù)據(jù)來模擬

「代碼」

wKgZomRl3kyAbciLAACKCIJNulY405.jpg
wKgaomRl3lSAMNvsAABxKltqJGg649.jpg

「測試」

可以看到:運行了八千多次的時候就內(nèi)存溢出了。

cca0d23e-e34f-11ed-ab56-dac502259ad0.png

我換了一臺 mac 電腦,4000 多就內(nèi)存溢出了。

ccc30232-e34f-11ed-ab56-dac502259ad0.png

不會內(nèi)存泄露的方案

「簡介」

內(nèi)部類改為靜態(tài)的之后,它所引用的對象或?qū)傩砸脖仨毷庆o態(tài)的,所以靜態(tài)內(nèi)部類無法獲得外部對象的引用,只能從 JVM 的 Method Area(方法區(qū))獲取到 static 類型的引用。

「代碼」

wKgZomRl3ouAEs_OAACRRLHwKvQ661.jpg
wKgZomRl3pKAFOqTAABqpeuEStM022.jpg

「測試」

可以發(fā)現(xiàn):循環(huán)了四十多萬次都沒有內(nèi)存溢出。

cce69c60-e34f-11ed-ab56-dac502259ad0.png





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • JAVA語言
    +關(guān)注

    關(guān)注

    0

    文章

    138

    瀏覽量

    20095
  • JVM
    JVM
    +關(guān)注

    關(guān)注

    0

    文章

    158

    瀏覽量

    12228

原文標(biāo)題:Java 內(nèi)部類有坑。。100 % 內(nèi)存泄露!

文章出處:【微信號:AndroidPush,微信公眾號:Android編程精選】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    Executors使用不當(dāng)引起的內(nèi)存泄漏怎么解決

    (TaskThread.java:61)  at java.lang.Thread.run(Thread.java:748)  看到了如上信息之后,大概可以看出是由于線程池的使用不當(dāng)
    發(fā)表于 12-23 17:38

    如何解決STM32串口溢出錯誤Overrun使用不當(dāng)導(dǎo)致的串口死機?

    如何解決STM32串口溢出錯誤Overrun使用不當(dāng)導(dǎo)致的串口死機?
    發(fā)表于 12-15 07:29

    MP3使用不當(dāng)會造成的健康問題

    MP3使用不當(dāng)會造成的健康問題 別看MP3這個小數(shù)碼產(chǎn)品,如果不正確使用說不定會損害你的身體健康。
    發(fā)表于 02-01 17:20 ?453次閱讀

    熱水器使用不當(dāng)易漏電傷人

    熱水器使用不當(dāng)易漏電傷人     重慶市消委近日發(fā)出消費警示,提醒消費者應(yīng)謹(jǐn)慎購買使用電熱水器,以防發(fā)生漏電傷人事故。 &nb
    發(fā)表于 02-21 16:47 ?1001次閱讀

    接口、內(nèi)部類Java API基礎(chǔ)

    理解接口的作用,理解接口和實現(xiàn)接口的類的關(guān)系,掌握聲明接口、一個類實現(xiàn)多個接口的聲明和使用方法。理解內(nèi)嵌類型的概念,掌握聲明內(nèi)部類的方法。熟悉Java語言包和實用包中的常用類。
    發(fā)表于 11-23 11:52 ?0次下載

    java內(nèi)部類分析詳解

    可以將一個類的定義放在另一個類的定義內(nèi)部,這就是內(nèi)部類內(nèi)部類是一個非常有用的特性但又比較難理解使用的特性(鄙人到現(xiàn)在都沒有怎么使用過內(nèi)部類,對內(nèi)
    發(fā)表于 09-27 14:59 ?0次下載

    java內(nèi)部類怎么寫

    一。內(nèi)部類基礎(chǔ) 二。深入理解內(nèi)部類 三。內(nèi)部類的使用場景和好處 四。常見的與內(nèi)部類相關(guān)的筆試面試題 若有不正之處,請多諒解并歡迎批評指正。 一。內(nèi)部
    發(fā)表于 09-27 16:15 ?0次下載
    <b class='flag-5'>java</b><b class='flag-5'>內(nèi)部類</b>怎么寫

    java開發(fā)中遇到的難點有哪些_java開發(fā)常見的問題及解決辦法

    本文主要介紹的是java開發(fā),首先介紹了java開發(fā)的過程,其次介紹了java開發(fā)中遇到的難點,最后闡述了java開發(fā)常見的問題及解決辦法,
    發(fā)表于 04-26 16:49 ?9.4w次閱讀

    潤滑油和潤滑脂使用不當(dāng)的幾種表現(xiàn)

    潤滑油和潤滑脂使用不當(dāng)的幾種表現(xiàn) 潤滑油(俗稱機油)和潤滑脂(俗稱黃油),在農(nóng)機維修保養(yǎng)中被廣泛應(yīng)用。正確使用潤滑油和潤滑脂關(guān)系到機械使用壽命的長短。最近,筆者在南昌市郊農(nóng)村調(diào)研中發(fā)現(xiàn)有些農(nóng)機
    的頭像 發(fā)表于 06-28 18:54 ?1325次閱讀

    Java內(nèi)部類持有外部類導(dǎo)致內(nèi)存泄露的原因以及其解決方案

    簡介 為什么要持有外部類 實例:持有外部類 實例:不持有外部類 實例:內(nèi)存泄露 不會內(nèi)存
    的頭像 發(fā)表于 10-08 16:32 ?980次閱讀

    java內(nèi)部類可以用public修飾嗎

    Java內(nèi)部類是指一個類被定義在另一個類的內(nèi)部。根據(jù)定義的位置和訪問權(quán)限的不同,內(nèi)部類可以分為四種:成員內(nèi)部類、靜態(tài)
    的頭像 發(fā)表于 11-21 10:23 ?1200次閱讀

    java內(nèi)存溢出的幾種原因和解決辦法

    內(nèi)存,但是如果程序中存在內(nèi)存泄漏(Memory Leak)或者使用不當(dāng)的數(shù)據(jù)結(jié)構(gòu)等問題,仍然有可能導(dǎo)致內(nèi)存溢出。下面將詳細(xì)介紹
    的頭像 發(fā)表于 11-23 14:44 ?6188次閱讀

    M16連接器8芯使用不當(dāng)會出現(xiàn)什么情況

      德索工程師說道M16連接器8芯,作為一種高性能的電氣連接器件,其正確使用對于整個系統(tǒng)的穩(wěn)定性和安全性至關(guān)重要。然而,如果使用不當(dāng),可能會引發(fā)一系列問題,從而影響系統(tǒng)的正常運行。以下是關(guān)于M16連接器8芯使用不當(dāng)可能出現(xiàn)的情況的詳細(xì)分析:
    的頭像 發(fā)表于 06-06 17:39 ?461次閱讀
    M16連接器8芯<b class='flag-5'>使用不當(dāng)</b>會出現(xiàn)什么情況

    MCX射頻頭使用不當(dāng)會出現(xiàn)什么情況

     德索工程師說道MCX射頻頭使用不當(dāng)可能會出現(xiàn)多種情況,這些問題不僅影響設(shè)備的性能,還可能對系統(tǒng)整體造成損害。以下是對MCX射頻頭使用不當(dāng)可能出現(xiàn)情況的詳細(xì)分析:  連接不穩(wěn):如果MCX射頻頭在
    的頭像 發(fā)表于 09-27 09:05 ?275次閱讀
    MCX射頻頭<b class='flag-5'>使用不當(dāng)</b>會出現(xiàn)什么情況

    注意,使用不當(dāng),陶瓷電容也會著火

    陶瓷電容因高頻特性好等被廣泛應(yīng)用,但過壓、短路、使用不當(dāng)、老化和品質(zhì)劣質(zhì)等因素易致其著火。使用時需注意選擇品質(zhì)好的陶瓷電容,避免風(fēng)險。
    的頭像 發(fā)表于 10-24 17:18 ?313次閱讀
    注意,<b class='flag-5'>使用不當(dāng)</b>,陶瓷電容也會著火