在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Java內部類持有外部類導致內存泄露的原因以及其解決方案

電子工程師 ? 來源: 芋道源碼 ? 作者: 芋道源碼 ? 2022-10-08 16:32 ? 次閱讀

簡介

為什么要持有外部類

實例:持有外部類

實例:不持有外部類

實例:內存泄露

不會內存泄露的方案

簡介

「說明」

本文介紹 Java 內部類持有外部類導致內存泄露的原因以及其解決方案。

「為什么內部類持有外部類會導致內存泄露?」

非靜態內部類會持有外部類,如果有地方引用了這個非靜態內部類,會導致外部類也被引用,垃圾回收時無法回收這個外部類(即使外部類已經沒有其他地方在使用了)。

「解決方案」

不要讓其他的地方持有這個非靜態內部類的引用,直接在這個非靜態內部類執行業務。

將非靜態內部類改為靜態內部類。內部類改為靜態的之后,它所引用的對象或屬性也必須是靜態的,所以靜態內部類無法獲得外部對象的引用,只能從 JVM 的 Method Area(方法區)獲取到static類型的引用。

基于 Spring Boot + MyBatis Plus + Vue & Element 實現的后臺管理系統 + 用戶小程序,支持 RBAC 動態權限、多租戶、數據權限、工作流、三方登錄、支付、短信、商城等功能

項目地址:https://gitee.com/zhijiantianya/ruoyi-vue-pro

視頻教程:https://doc.iocoder.cn/video/

為什么要持有外部類

Java 語言中,非靜態內部類的主要作用有兩個:

當內部類只在外部類中使用時,匿名內部類可以讓外部不知道它的存在,從而減少了代碼的維護工作。

當內部類持有外部類時,它就可以直接使用外部類中的變量了,這樣可以很方便的完成調用,如下代碼所示:

packageorg.example.a;

classOuter{
privateStringouterName="Tony";

classInner{
privateStringname;

publicInner(){
this.name=outerName;
}
}

InnercreateInner(){
returnnewInner();
}
}

publicclassDemo{
publicstaticvoidmain(String[]args){
Outer.Innerinner=newOuter().createInner();
System.out.println(inner);
}
}

但是,靜態內部類就無法持有外部類和其非靜態字段了。比如下邊這樣就會報錯

packageorg.example.a;

classOuter{
privateStringouterName="Tony";

staticclassInner{
privateStringname;

publicInner(){
this.name=outerName;
}
}

InnercreateInner(){
returnnewInner();
}
}

publicclassDemo{
publicstaticvoidmain(String[]args){
Outer.Innerinner=newOuter().createInner();
System.out.println(inner);
}
}

報錯:

9985cd7a-46ae-11ed-96c9-dac502259ad0.png

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實現的后臺管理系統 + 用戶小程序,支持 RBAC 動態權限、多租戶、數據權限、工作流、三方登錄、支付、短信、商城等功能

項目地址:https://gitee.com/zhijiantianya/yudao-cloud

視頻教程:https://doc.iocoder.cn/video/

實例:持有外部類

「代碼」

packageorg.example.a;

classOuter{
classInner{

}

InnercreateInner(){
returnnewInner();
}
}

publicclassDemo{
publicstaticvoidmain(String[]args){
Outer.Innerinner=newOuter().createInner();
System.out.println(inner);
}
}

「斷點調試」

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

99a23ec4-46ae-11ed-96c9-dac502259ad0.png

實例:不持有外部類

「代碼」

packageorg.example.a;

classOuter{
staticclassInner{

}

InnercreateInner(){
returnnewInner();
}
}

publicclassDemo{
publicstaticvoidmain(String[]args){
Outer.Innerinner=newOuter().createInner();
System.out.println(inner);
}
}

「斷點調試」

可以發現:內部類不再持有外部類了。

99c4316e-46ae-11ed-96c9-dac502259ad0.png

實例:內存泄露

「簡介」

若內部類持有外部類的引用,對內部類的使用很多時,會導致外部類數目很多。此時,就算是外部類的數據沒有被用到,外部類的數據所占空間也不會被釋放。

本處在外部類存放大量的數據來模擬

「代碼」

packageorg.example.a;

importjava.util.ArrayList;
importjava.util.List;

classOuter{
privateint[]data;

publicOuter(intsize){
this.data=newint[size];
}

classInnner{

}

InnnercreateInner(){
returnnewInnner();
}
}

publicclassDemo{
publicstaticvoidmain(String[]args){
Listlist=newArrayList<>();
intcounter=0;
while(true){
list.add(newOuter(100000).createInner());
System.out.println(counter++);
}
}
}

「測試」

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

99d10b96-46ae-11ed-96c9-dac502259ad0.png

換了一臺 mac 電腦,4000 多就內存溢出了。

99f6a4c8-46ae-11ed-96c9-dac502259ad0.png

不會內存泄露的方案

「簡介」

內部類改為靜態的之后,它所引用的對象或屬性也必須是靜態的,所以靜態內部類無法獲得外部對象的引用,只能從 JVM 的 Method Area(方法區)獲取到 static 類型的引用。

「代碼」

packageorg.example.a;

importjava.util.ArrayList;
importjava.util.List;

classOuter{
privateint[]data;

publicOuter(intsize){
this.data=newint[size];
}

staticclassInner{

}

InnercreateInner(){
returnnewInner();
}
}

publicclassDemo{
publicstaticvoidmain(String[]args){
Listlist=newArrayList<>();
intcounter=0;
while(true){
list.add(newOuter(100000).createInner());
System.out.println(counter++);
}
}
}

「測試」

可以發現:循環了四十多萬次都沒有內存溢出。

9a1f2cfe-46ae-11ed-96c9-dac502259ad0.png

以上,希望能對大家在使用內部類時會有所幫助。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 內存
    +關注

    關注

    8

    文章

    3025

    瀏覽量

    74056
  • JAVA
    +關注

    關注

    19

    文章

    2967

    瀏覽量

    104758
  • JVM
    JVM
    +關注

    關注

    0

    文章

    158

    瀏覽量

    12228
  • static
    +關注

    關注

    0

    文章

    33

    瀏覽量

    10372

原文標題:Java內部類有坑,100%內存泄露!

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    Java知識:內部類與匿名類_內部類#Java

    JAVA
    學習電子
    發布于 :2022年11月16日 01:30:13

    Java基礎知識:內部類和匿名內部類#Java

    JAVA
    學習硬聲知識
    發布于 :2022年11月16日 17:55:25

    java rules下載/java規范中文版

    使用SDK創建包2.5 導入聲明2.5.1 自動導入2.5.2 冗余導入2.5.3 各種嵌套類的導入(頂層類或內部類)2.5.4 編譯器對導入語句的解析2.5.5 按需類型導入聲明的效能2.6 類型聲明
    發表于 06-23 18:16

    java基礎知識精講視頻教程百度云盤分享!

    日歷57 java日期58 Math與Random59 內部類60 單例模式61 工廠模式62 線程的創建63 使用runnable創建線程64 tcp編程一65 網絡編程二66 對象的clone67
    發表于 07-12 11:50

    ARM之靜態變量簡析

    靜態變量的值可以一直保持到程序結束,使用關鍵字static可以將變量聲明為靜態的:static int x ;static float y;根據聲明的位置不同,靜態變量也可以分為內部類型或外部類
    發表于 04-24 09:27

    對在Firefly-RK3288開發板上的Hello進行內存泄漏分析常見實例

    、GiftLetl. regNewMsgHandler后,在退出fragment后雖然手動設為null,但是因為原來那個已經設置另一進程而導致內存泄漏實例4、內部類中使用宿主類變量(截圖中是ListView的Adapter),而
    發表于 09-22 14:46

    接口、內部類Java API基礎

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

    java內部類分析詳解

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

    java內部類怎么寫

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

    內存溢出和內存泄露的區別_內存溢出的原因以及解決方法

    內存溢出和內存泄露的區別是什么?內存溢出怎么解決?內存溢出是指程序在申請內存時,沒有足夠的
    發表于 06-01 10:27 ?2917次閱讀

    Java內部類使用不當導致內存泄露問題及解決辦法

    非靜態內部類持有外部類,如果有地方引用了這個非靜態內部類,會導致外部類也被引用,垃圾回收時無法
    的頭像 發表于 05-18 16:09 ?1137次閱讀
    <b class='flag-5'>Java</b><b class='flag-5'>內部類</b>使用不當<b class='flag-5'>導致</b>的<b class='flag-5'>內存</b><b class='flag-5'>泄露</b>問題及解決辦法

    static定義內部類

    1. static定義內部類 1.1 static定義內部類 如果說現在內部類上使用了static定義,那么這個內部類就變成了“外部類”,s
    的頭像 發表于 10-10 16:08 ?557次閱讀

    如何在普通類中使用內部結構

    class Test { public static void main ( String [] args ) { Outer outer = new Outer(); outer.fun(); }} 創建外部類的實例調用外部類的方法卻執行了
    的頭像 發表于 10-10 16:26 ?431次閱讀

    java內部類可以用public修飾嗎

    使用任意訪問權限修飾符,包括public、protected、默認和private。 方法內部類只能使用默認訪問權限,即不加任何訪問修飾符。 使用public修飾的內部類 內部類使用public修飾時,可以被
    的頭像 發表于 11-21 10:23 ?1199次閱讀

    java內存溢出的幾種原因和解決辦法

    內存,但是如果程序中存在內存泄漏(Memory Leak)或者使用不當的數據結構等問題,仍然有可能導致內存溢出。下面將詳細介紹Java
    的頭像 發表于 11-23 14:44 ?6185次閱讀
    主站蜘蛛池模板: 国内精品久久久久影院免费| 91久久国产青草亚洲| 免费在线公开视频| 亚洲成a人片在线观看导航| 狼色影院| 污女网站| a欧美在线| 777精品视频| 婷婷影院在线综合免费视频| 国产精品不卡片视频免费观看 | 久久国产视频网站| 爱爱帝国亚洲一区二区三区| 噜噜色噜噜| 女色窝人体色77777| 国产免费久久精品99| 噜噜色噜噜色| 国产精品福利午夜在线观看| 亚洲伊人99综合网| 国产精品情人露脸在线观看| 1024手机在线观看视频| 天堂在线精品| 在线看欧美成人中文字幕视频| 91华人在线视频| 欧美精品福利| 精品乱人伦一区二区三区| 亚洲美女视频在线观看| www.瑟瑟| 色吧在线视频在线观看| 久久精品亚瑟全部免费观看| 国产免费午夜| 色播.com| 欧美8888| 午夜欧美成人久久久久久| 永久免费精品影视网站| 美女被免费网站在线视频九色| 激情 婷婷| 免费高清在线视频色yeye| 日本a网站| 国产午夜视频在线观看| 五月综合色| 天天想天天干|