最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2022年11月23日 11:33:46   作者:IT利刃出鞘  
這篇文章主要為大家詳細(xì)介紹了Java因?yàn)閮?nèi)部類持有外部類導(dǎo)致內(nèi)存泄露的原因以及其解決方案,文中的示例代碼講解詳細(xì),希望對(duì)大家有所幫助

簡(jiǎn)介

說(shuō)明

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

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

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

解決方案

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

2.將非靜態(tài)內(nèi)部類改為靜態(tài)內(nèi)部類。

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

相關(guān)網(wǎng)址

匿名內(nèi)部類的內(nèi)存泄露:Java的匿名內(nèi)部類導(dǎo)致內(nèi)存泄露--原因/解決方案

為什么要持有外部類

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

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

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

package org.example.a;
 
class Outer{
    private String outerName = "Tony";
 
    class Inner{
        private String name;
 
        public Inner() {
            this.name = outerName;
        }
    }
 
    Inner createInner() {
        return new Inner();
    }
}
 
public class Demo {
    public static void main(String[] args) {
        Outer.Inner inner = new Outer().createInner();
        System.out.println(inner);
    }
}

但是,靜態(tài)內(nèi)部類就無(wú)法持有外部類和其非靜態(tài)字段了。比如下邊這樣就會(huì)報(bào)錯(cuò)

package org.example.a;
 
class Outer{
    private String outerName = "Tony";
 
    static class Inner{
        private String name;
 
        public Inner() {
            this.name = outerName;
        }
    }
 
    Inner createInner() {
        return new Inner();
    }
}
 
public class Demo {
    public static void main(String[] args) {
        Outer.Inner inner = new Outer().createInner();
        System.out.println(inner);
    }
}

報(bào)錯(cuò): 

實(shí)例:持有外部類

代碼

package org.example.a;
 
class Outer{
    class Inner {
 
    }
 
    Inner createInner() {
        return new Inner();
    }
}
 
public class Demo {
    public static void main(String[] args) {
        Outer.Inner inner = new Outer().createInner();
        System.out.println(inner);
    }
}

斷點(diǎn)調(diào)試

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

實(shí)例:不持有外部類

代碼

package org.example.a;
 
class Outer{
    static class Inner {
 
    }
 
    Inner createInner() {
        return new Inner();
    }
}
 
public class Demo {
    public static void main(String[] args) {
        Outer.Inner inner = new Outer().createInner();
        System.out.println(inner);
    }
}

斷點(diǎn)調(diào)試

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

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

簡(jiǎn)介

若內(nèi)部類持有外部類的引用,對(duì)內(nèi)部類的使用很多時(shí),會(huì)導(dǎo)致外部類數(shù)目很多。此時(shí),就算是外部類的數(shù)據(jù)沒(méi)有被用到,外部類的數(shù)據(jù)所占空間也不會(huì)被釋放。

本處在外部類存放大量的數(shù)據(jù)來(lái)模擬。

代碼

package org.example.a;
 
import java.util.ArrayList;
import java.util.List;
 
class Outer{
    private int[] data;
 
    public Outer(int size) {
        this.data = new int[size];
    }
 
    class Innner{
 
    }
 
    Innner createInner() {
        return new Innner();
    }
}
 
public class Demo {
    public static void main(String[] args) {
        List<Object> list = new ArrayList<>();
        int counter = 0;
        while (true) {
            list.add(new Outer(100000).createInner());
            System.out.println(counter++);
        }
    }
}

測(cè)試

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

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

簡(jiǎn)介

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

代碼 

package org.example.a;
 
import java.util.ArrayList;
import java.util.List;
 
class Outer{
    private int[] data;
 
    public Outer(int size) {
        this.data = new int[size];
    }
 
    static class Inner {
 
    }
 
    Inner createInner() {
        return new Inner();
    }
}
 
public class Demo {
    public static void main(String[] args) {
        List<Object> list = new ArrayList<>();
        int counter = 0;
        while (true) {
            list.add(new Outer(100000).createInner());
            System.out.println(counter++);
        }
    }
}

測(cè)試

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

以上就是Java內(nèi)部類持有外部類導(dǎo)致內(nèi)存泄露的原因與解決方案詳解的詳細(xì)內(nèi)容,更多關(guān)于Java內(nèi)存泄露的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • MyBatis配置文件元素示例詳解

    MyBatis配置文件元素示例詳解

    在MyBatis框架的核心配置文件中,<configuration>元素是配置文件的根元素,其他元素都要在<contiguration>元素內(nèi)配置,這篇文章主要介紹了MyBatis配置文件元素,需要的朋友可以參考下
    2023-06-06
  • Jmeter非GUI模式運(yùn)行分布式測(cè)試

    Jmeter非GUI模式運(yùn)行分布式測(cè)試

    這篇文章主要介紹了Jmeter非GUI模式運(yùn)行分布式測(cè)試,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • SpringBoot3實(shí)現(xiàn)國(guó)際化的代碼步驟

    SpringBoot3實(shí)現(xiàn)國(guó)際化的代碼步驟

    國(guó)際化,簡(jiǎn)稱 i18n,源自國(guó)際化英文單詞 internationalization 中首字母 i 與尾字母 n 之間有 18 個(gè)字母,本文給大家介紹了SpringBoot3實(shí)現(xiàn)國(guó)際化的操作步驟,并通過(guò)代碼示例講解的非常詳細(xì),需要的朋友可以參考下
    2024-12-12
  • Springboot?+redis+谷歌開(kāi)源Kaptcha實(shí)現(xiàn)圖片驗(yàn)證碼功能

    Springboot?+redis+谷歌開(kāi)源Kaptcha實(shí)現(xiàn)圖片驗(yàn)證碼功能

    這篇文章主要介紹了Springboot?+redis+?歌開(kāi)源Kaptcha實(shí)現(xiàn)圖片驗(yàn)證碼功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-01-01
  • 基于spring?data?jpa?@query返回map的踩坑記錄

    基于spring?data?jpa?@query返回map的踩坑記錄

    這篇文章主要介紹了基于spring?data?jpa?@query返回map的踩坑記錄,具有很好的參考價(jià)值,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java ArrayList使用總結(jié)

    Java ArrayList使用總結(jié)

    這篇文章主要介紹了Java ArrayList使用總結(jié),幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下
    2021-03-03
  • Spring Boot中使用Server-Sent Events (SSE) 實(shí)現(xiàn)實(shí)時(shí)數(shù)據(jù)推送教程

    Spring Boot中使用Server-Sent Events (SSE) 實(shí)

    Server-Sent Events (SSE) 是HTML5引入的一種輕量級(jí)的服務(wù)器向?yàn)g覽器客戶端單向推送實(shí)時(shí)數(shù)據(jù)的技術(shù),本文主要介紹了Spring Boot中使用Server-Sent Events (SSE) 實(shí)現(xiàn)實(shí)時(shí)數(shù)據(jù)推送教程,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • Bloc事件流是一個(gè)阻塞隊(duì)列結(jié)論解析

    Bloc事件流是一個(gè)阻塞隊(duì)列結(jié)論解析

    這篇文章主要為大家介紹了Bloc事件流是一個(gè)阻塞隊(duì)列結(jié)論解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • java 對(duì)文件夾目錄進(jìn)行深度遍歷實(shí)例代碼

    java 對(duì)文件夾目錄進(jìn)行深度遍歷實(shí)例代碼

    這篇文章主要介紹了java 對(duì)文件夾目錄進(jìn)行深度遍歷實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • Java通過(guò)遞歸算法解決迷宮與漢諾塔及八皇后問(wèn)題

    Java通過(guò)遞歸算法解決迷宮與漢諾塔及八皇后問(wèn)題

    方法就是用來(lái)完成解決某件事情或?qū)崿F(xiàn)某個(gè)功能的辦法;程序調(diào)用自身的編程技巧稱為遞歸,本文主要講的是通過(guò)遞歸來(lái)實(shí)現(xiàn)三個(gè)經(jīng)典的問(wèn)題,解決迷宮,漢諾塔,八皇后問(wèn)題,感興趣的朋友可以參考一下
    2022-05-05

最新評(píng)論

奉化市| 洛扎县| 广州市| 根河市| 布拖县| 伊宁市| 盐津县| 布拖县| 天等县| 江安县| 盘山县| 阿拉善盟| 禄丰县| 陆河县| 贺州市| 枞阳县| 白河县| 湘乡市| 阳西县| 凤山市| 扬中市| 南城县| 临潭县| 临安市| 贺兰县| 鸡泽县| 普陀区| 枝江市| 涪陵区| 福贡县| 易门县| 清原| 澎湖县| 屏边| 闽侯县| 长汀县| 启东市| 大港区| 阿坝| 炎陵县| 桐柏县|