网易首页 > 网易号 > 正文 申请入驻

Java内部类有坑,100%内存泄露!

0
分享至

今天给大家分享一种,Java内部类使用不当导致的内存泄露问题,最终导致内存溢出!希望能够帮助到大家!

「说明」

本文介绍 Java 内部类持有外部类导致内存泄露的原因以及其解决方案。今天给大家分享一种,Java内部类使用不当导致的内存泄露问题,最终导致内存溢出!希望能够帮助到大家!

「为什么内部类持有外部类会导致内存泄露?」

非静态内部类会持有外部类,如果有地方引用了这个非静态内部类,会导致外部类也被引用,垃圾回收时无法回收这个外部类(即使外部类已经没有其他地方在使用了)。

「解决方案」

  1. 不要让其他的地方持有这个非静态内部类的引用,直接在这个非静态内部类执行业务。

  2. 将非静态内部类改为静态内部类。内部类改为静态的之后,它所引用的对象或属性也必须是静态的,所以静态内部类无法获得外部对象的引用,只能从 JVM 的 Method Area(方法区)获取到static类型的引用。


Java 语言中,非静态内部类的主要作用有两个:

  1. 当内部类只在外部类中使用时,匿名内部类可以让外部不知道它的存在,从而减少了代码的维护工作。

  2. 当内部类持有外部类时,它就可以直接使用外部类中的变量了,这样可以很方便的完成调用,如下代码所示:

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

但是,静态内部类就无法持有外部类和其非静态字段了。比如下边这样就会报错

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

报错:

实例:持有外部类

「代码」

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

「断点调试」

可以看到:内部类持有外部类的对象的引用,是以“this$0”这个字段来保存的。面试宝典:https://www.yoodb.com

实例:不持有外部类

「代码」

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

「断点调试」

可以发现:内部类不再持有外部类了。Java系列新特性:https://www.yoodb.com/java/characteristic/java-8/Java8-optional.html

实例:内存泄露

「简介」

若内部类持有外部类的引用,对内部类的使用很多时,会导致外部类数目很多。此时,就算是外部类的数据没有被用到,外部类的数据所占空间也不会被释放。

本处在外部类存放大量的数据来模拟。

「代码」

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 list = new ArrayList<>();
int counter = 0;
while ( true) {
list.add( new Outer( 100000).createInner());
System.out.println(counter++);
}
}
}

「测试」

可以看到:运行了八千多次的时候就内存溢出了。

我换了一台 mac 电脑,4000 多就内存溢出了。

「简介」

内部类改为静态的之后,它所引用的对象或属性也必须是静态的,所以静态内部类无法获得外部对象的引用,只能从 JVM 的 Method Area(方法区)获取到 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 list = new ArrayList<>();
int counter = 0;
while ( true) {
list.add( new Outer( 100000).createInner());
System.out.println(counter++);
}
}
}

「测试」

可以发现:循环了四十多万次都没有内存溢出。 公众 号 Java精选,回复java面试,获取面试资料,支持在线刷题。


作者:IT利刃出鞘 https://knife.blog.csdn.net/

公众号“Java精选”所发表内容注明来源的,版权归原出处所有(无法查证版权的或者未注明出处的均来自网络,系转载,转载的目的在于传递更多信息,版权属于原作者。如有侵权,请联系,笔者会第一时间删除处理!

最近有很多人问,有没有读者交流群!加入方式很简单,公众号Java精选,回复“加群”,即可入群!

(微信小程序):3000+道面试题,包含Java基础、并发、JVM、线程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架构设计等,在线随时刷题!

------ 特别推荐 ------

特别推荐:专注分享最前沿的技术与资讯,为弯道超车做好准备及各种开源项目与高效率软件的公众号,「大咖笔记」,专注挖掘好东西,非常值得大家关注。点击下方公众号卡片关注

文章有帮助的话,点在看,转发吧!

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
U17世界杯小组赛赛程公布,国少比赛将在23点和0点进行

U17世界杯小组赛赛程公布,国少比赛将在23点和0点进行

狗哥是一名内拉
2026-06-02 10:04:24
胡锡进大赞华为韬定律:这是敲响美国科技霸权的丧钟

胡锡进大赞华为韬定律:这是敲响美国科技霸权的丧钟

映射生活的身影
2026-05-31 22:44:35
“穷养女真可怜”,买10分钟商务坐拍了9分钟,鞋子让人无语

“穷养女真可怜”,买10分钟商务坐拍了9分钟,鞋子让人无语

泽泽先生
2026-04-09 21:36:08
曾经月销四五万的神车,为何集体消失了?

曾经月销四五万的神车,为何集体消失了?

大佬灼见
2026-06-02 11:09:30
黄仁勋到底有没有误读“韬定律”?

黄仁勋到底有没有误读“韬定律”?

观察者网
2026-06-02 08:42:08
主角大结局:胡三元花彩香结婚,刘红兵没死,封潇潇成武戏演员

主角大结局:胡三元花彩香结婚,刘红兵没死,封潇潇成武戏演员

八卦南风
2026-06-02 10:48:18
吉林省严打!为期3个月

吉林省严打!为期3个月

吉刻新闻
2026-06-02 14:50:59
美媒:中国逻辑折叠技术一旦被国际掌握,ASML将首当其冲

美媒:中国逻辑折叠技术一旦被国际掌握,ASML将首当其冲

赵钇是个热血青年
2026-06-02 12:59:12
“都把儿子养雌化了!”初中男孩出现雌化现象,家长却执迷不悟

“都把儿子养雌化了!”初中男孩出现雌化现象,家长却执迷不悟

妍妍教育日记
2026-05-29 07:55:13
吃完嫩的吃老的,山西儿媳出轨公公10年,亲自给丈夫生下一个妹妹

吃完嫩的吃老的,山西儿媳出轨公公10年,亲自给丈夫生下一个妹妹

莫地方
2026-06-02 00:10:26
2-0横扫晋级!中国女网15岁天才夺11连胜:世界第2当李娜接班人?

2-0横扫晋级!中国女网15岁天才夺11连胜:世界第2当李娜接班人?

李喜林篮球绝杀
2026-06-01 20:21:13
李善长被处死时已年近80,每天耕地种田,朱元璋为何非要斩他满门

李善长被处死时已年近80,每天耕地种田,朱元璋为何非要斩他满门

千秋文化
2025-12-27 21:50:26
为什么领导都喜欢上班?网友曝光领导抽屉都是性用品:丝袜、套套

为什么领导都喜欢上班?网友曝光领导抽屉都是性用品:丝袜、套套

黯泉
2026-06-01 15:33:05
女儿跌落悬崖死亡,母亲每天向悬崖下面扔食物,三年后奇迹出现

女儿跌落悬崖死亡,母亲每天向悬崖下面扔食物,三年后奇迹出现

乔生桂
2024-08-22 16:43:20
女子银行取现75万要“开店” 民警苦劝4小时保住血汗钱

女子银行取现75万要“开店” 民警苦劝4小时保住血汗钱

上游新闻
2026-06-02 18:12:07
四人吃火锅要求免单后续:用5000字差评威胁老板,真容曝光已社死

四人吃火锅要求免单后续:用5000字差评威胁老板,真容曝光已社死

娱乐的硬糖吖
2026-06-01 12:26:56
拿到了!余嘉豪队内MVP!中国男篮最新甜蜜烦恼

拿到了!余嘉豪队内MVP!中国男篮最新甜蜜烦恼

篮球实战宝典
2026-06-01 22:18:48
央视再曝新毒物!长期用会致癌,已流窜至全国,婴儿孕妇需警惕

央视再曝新毒物!长期用会致癌,已流窜至全国,婴儿孕妇需警惕

杰丝聊古今
2026-06-02 18:00:05
“冤不冤?”内蒙古,一女子还在哺乳期,就开始做上门按摩服务

“冤不冤?”内蒙古,一女子还在哺乳期,就开始做上门按摩服务

阿振观点
2026-06-01 20:09:42
女友嫌我家穷提出分手,20年后,我就任市里领导,在聚会上遇见她

女友嫌我家穷提出分手,20年后,我就任市里领导,在聚会上遇见她

千秋文化
2026-05-29 19:58:13
2026-06-02 18:48:49
Java精选
Java精选
一场永远也演不完的戏
1792文章数 3859关注度
往期回顾 全部

科技要闻

烧掉千亿后,美团、阿里、京东谁先止血?

头条要闻

5岁儿子29万存款被妈妈取到剩40块 爸爸起诉法院判了

头条要闻

5岁儿子29万存款被妈妈取到剩40块 爸爸起诉法院判了

体育要闻

1米74的业余联赛替补,在英超踢中卫

娱乐要闻

奚梦瑶何猷君补办婚礼超幸福

财经要闻

智元和宇树的“暗战”愈演愈烈

汽车要闻

星途神秘新车轮廓曝光 又一款性能SUV要来了?

态度原创

教育
亲子
房产
公开课
军事航空

教育要闻

中考压轴题,难倒很多人,看看学霸如何求解

亲子要闻

闪闪小葵花成长正当时

房产要闻

5200巨量投资曝光!未来五年,海南格局大变!

公开课

李玫瑾:为什么性格比能力更重要?

军事要闻

伊朗媒体新发布最高领袖照片

无障碍浏览 进入关怀版