国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

注意避坑!Java 內(nèi)部類持有外部類會導(dǎo)致內(nèi)存泄露。。。

這篇具有很好參考價值的文章主要介紹了注意避坑!Java 內(nèi)部類持有外部類會導(dǎo)致內(nèi)存泄露。。。。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

簡介

說明

本文介紹 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類型的引用。

推薦一個開源免費(fèi)的 Spring Boot 實(shí)戰(zhàn)項(xiàng)目:

https://github.com/javastacks/spring-boot-best-practice

為什么要持有外部類

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

  • 當(dāng)內(nèi)部類只在外部類中使用時,匿名內(nèi)部類可以讓外部不知道它的存在,從而減少了代碼的維護(hù)工作。
  • 當(dāng)內(nèi)部類持有外部類時,它就可以直接使用外部類中的變量了,這樣可以很方便的完成調(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)部類就無法持有外部類和其非靜態(tài)字段了。

比如下邊這樣就會報(bào)錯:

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)錯:

注意避坑!Java 內(nèi)部類持有外部類會導(dǎo)致內(nèi)存泄露。。。

實(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)部類持有外部類的對象的引用,是以“this$0”這個字段來保存的。

注意避坑!Java 內(nèi)部類持有外部類會導(dǎo)致內(nèi)存泄露。。。

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

推薦一個開源免費(fèi)的 Spring Boot 實(shí)戰(zhàn)項(xiàng)目:

https://github.com/javastacks/spring-boot-best-practice

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)部類不再持有外部類了。

注意避坑!Java 內(nèi)部類持有外部類會導(dǎo)致內(nèi)存泄露。。。

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

簡介

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

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

代碼

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++);
        }
    }
}

測試

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

注意避坑!Java 內(nèi)部類持有外部類會導(dǎo)致內(nèi)存泄露。。。

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

注意避坑!Java 內(nèi)部類持有外部類會導(dǎo)致內(nèi)存泄露。。。

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

簡介

內(nèi)部類改為靜態(tài)的之后,它所引用的對象或?qū)傩砸脖仨毷庆o態(tài)的,所以靜態(tài)內(nèi)部類無法獲得外部對象的引用,只能從 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++);
        }
    }
}

測試

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

注意避坑!Java 內(nèi)部類持有外部類會導(dǎo)致內(nèi)存泄露。。。

來源:blog.csdn.net/feiying0canglang/article/details/121108201

近期熱文推薦:

1.1,000+ 道 Java面試題及答案整理(2022最新版)

2.勁爆!Java 協(xié)程要來了。。。

3.Spring Boot 2.x 教程,太全了!

4.別再寫滿屏的爆爆爆炸類了,試試裝飾器模式,這才是優(yōu)雅的方式??!

5.《Java開發(fā)手冊(嵩山版)》最新發(fā)布,速速下載!

覺得不錯,別忘了隨手點(diǎn)贊+轉(zhuǎn)發(fā)哦!文章來源地址http://www.zghlxwxcb.cn/news/detail-707950.html

到了這里,關(guān)于注意避坑!Java 內(nèi)部類持有外部類會導(dǎo)致內(nèi)存泄露。。。的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 避坑之路 —— 前后端 json 的注意問題

    避坑之路 —— 前后端 json 的注意問題

    當(dāng)我們在進(jìn)行開發(fā)項(xiàng)目的時候,在前后端需要進(jìn)行數(shù)據(jù)之間的傳輸,那么就會需要到j(luò)son。而json算是字符串中的一種 1.先說一下前端的, 其實(shí)這兩種都是表示前端希望能收到后端json這樣的數(shù)據(jù)格式,那么我們在后端就需要注意將數(shù)據(jù)進(jìn)行轉(zhuǎn)換為json進(jìn)行返回 2.后端 這里我就說一

    2024年02月09日
    瀏覽(19)
  • java根據(jù)身份證號計(jì)算持有者年齡--超容易

    主要思路很簡單: 1.通過當(dāng)前年份和用戶出生年份相減計(jì)算出age :用戶當(dāng)年還沒過生的話,age要減一。 2.在身份證截取根據(jù)“ 月日 ”拼接成開頭可以為0的 四位數(shù)int值 。根據(jù) 當(dāng)前月日 值和用戶 出生月日 對比大小,一步判斷age是否要減一。避免了月份判斷月份相同等和日期

    2024年02月12日
    瀏覽(26)
  • android內(nèi)部存儲和外部存儲

    android內(nèi)部存儲和外部存儲

    我們在開發(fā)Android應(yīng)用的過程中,避免不了要用到數(shù)據(jù)持久化技術(shù),所謂的數(shù)據(jù)持久化就是將RAM中的瞬時數(shù)據(jù)保存到ROM中,保證在App退出或者手機(jī)關(guān)機(jī)后數(shù)據(jù)不會丟失。我們常用的數(shù)據(jù)持久化的方式有文件存儲,數(shù)據(jù)庫存儲,SharedPreference存儲等。在window中,當(dāng)我們存儲文件或

    2024年02月09日
    瀏覽(13)
  • 內(nèi)部表與外部表——頭歌

    任務(wù)描述 本關(guān)任務(wù):創(chuàng)建外部表,并導(dǎo)入數(shù)據(jù)。 相關(guān)知識 為了完成本關(guān)任務(wù),你需要掌握:1.表的各種操作。 內(nèi)部表和外部表 Hive 默認(rèn)創(chuàng)建內(nèi)部表(managed table),存儲位置在 hive.metastore.warehouse.dir 設(shè)置,默認(rèn)位置是 /user/hive/warehouse。導(dǎo)入數(shù)據(jù)到內(nèi)部表的時候是將文件剪切(

    2024年02月08日
    瀏覽(17)
  • Android外部存儲與內(nèi)部存儲詳解

    內(nèi)部儲存(內(nèi)部存儲的文件夾其他應(yīng)用和用戶無法直接訪問,可以用于存放敏感數(shù)據(jù)。app進(jìn)行數(shù)據(jù)清理或卸載可以清理外部存儲和內(nèi)部存儲下的所有文件目錄, 不需要讀寫權(quán)限 ) getFilesDir() /data/data/包名/files 或者 /data/user/0/包名/files getCacheDir() /data/data/包名/cache 或者 /data/u

    2024年04月09日
    瀏覽(32)
  • Hive內(nèi)部表和外部表

    Hive內(nèi)部表和外部表

    表分類 在Hive中,表類型主要分為兩種 第一種: 內(nèi)部表 也叫管理表 表目錄會創(chuàng)建在集群上的{hive.metastore.warehouse.dir}下的相應(yīng)的庫對應(yīng)的目錄中。 默認(rèn)創(chuàng)建的表就是內(nèi)部表 第二種: 外部表 外部表需要使用\\\"external\\\", 外部表會根據(jù)創(chuàng)建表時LOCATION指定的路徑來創(chuàng)建目錄,

    2024年02月15日
    瀏覽(17)
  • Hive內(nèi)部表及外部表

    Hive內(nèi)部表及外部表

    內(nèi)部表,也叫托管表,是Hive在創(chuàng)建表時的默認(rèn)表。 特點(diǎn):在內(nèi)部表被刪除后,表的元數(shù)據(jù)和表數(shù)據(jù)都從HDFS中完全刪除 create table if not exists 表名( 字段名稱 字段類型, ... 字段名稱 字段類型 ) comment 表的注釋 raw format delimited fields terminated by \\\'分隔符\\\'? #列以\\\'分隔符\\\'分割 line?

    2024年02月05日
    瀏覽(20)
  • docker容器內(nèi)部可以訪問,外部無法訪問

    docker容器內(nèi)部可以訪問,外部無法訪問

    外部無法訪問nginx :將docker容器部署后臺運(yùn)行后,發(fā)現(xiàn)無法通過ip(宿主機(jī)ip地址,可以通過ifconfig去查看eno***的inet地址便可,也可直接填寫localhost):80(例如: localhost:80 )去訪問卻發(fā)現(xiàn)訪問失敗 內(nèi)部訪問成功 :于是我想先看看docker內(nèi)部是否可以訪問得到,先檢查nginx是否開

    2023年04月08日
    瀏覽(21)
  • 避坑:.NET內(nèi)存泄露的幾種情況

    內(nèi)存“泄露”是開發(fā)中常見的問題之一,它會導(dǎo)致應(yīng)用程序占用越來越多的內(nèi)存資源,最終可能導(dǎo)致系統(tǒng)性能下降甚至崩潰。軟件開發(fā)者需要了解在程序中出現(xiàn)內(nèi)存泄露的情況,以避免軟件出現(xiàn)該的問題。 什么是內(nèi)存“泄露”? 內(nèi)存泄露是申請了內(nèi)存空間的變量一直在占用

    2024年02月11日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包