java踩坑记之双花括号初始化实例导致内存泄露
2020-12-26 22:28
标签:https ret ice asList 参考 问题 class 回收 rgs 先来看一段代码: 通过javac编译后,生成文件:DoubleBracesTest.class 和 DoubleBracesTest$1.class,确认上面的代码中的"{{"的方式写法,采用了内部类来实现的。 用IDEA查看 DoubleBracesTest$1.class : 其中的 this.this$0 = var1 代表内部类持有了外部类的引用。 对应的字节码: 字节码中的 putfield这一行,这里表示有一个对DoubleBracesTest的引用被存在了 this$0 中,也就是说它持有了外部类的对象。 test方法返回一个map,如果被其他对象的属性所引用,GC时便不会回收此对象,从而导致内存泄漏!这个也是非静态内部类的主要缺点。 非静态匿名内部类持有外部类可以总结为以下两个作用 : 1.当匿名内部类只在外部类(主类)中使用时,匿名内部类可以让外部不知道它的存在,从而减少了代码的维护工作。 2.当匿名内部类持有外部类时,它就可以直接使用外部类中的变量了,这样可以很方便的完成调用。 1、上述调用方法改成static方法 匿名内部类是静态的之后,它所引用的对象或属性也必须是静态的了,因此就可以直接从 JVM 的 Method Area(方法区)获取到引用而无需持久外部对象了,也就不会持有外部类的引用了。 但是后期难保不会有人将 static 关键字删掉,那样问题又会出现了! 2、 参考 https://www.ripjava.com/article/1291630596325408 https://www.cnblogs.com/wenbronk/p/7000643.html https://cloud.tencent.com/developer/article/1632486 https://cloud.tencent.com/developer/article/1179625 https://hacpai.com/article/1498563483898 java踩坑记之双花括号初始化实例导致内存泄露 标签:https ret ice asList 参考 问题 class 回收 rgs 原文地址:https://www.cnblogs.com/ericli-ericli/p/13034709.html问题描述
public class DoubleBracesTest {
private String key = "key";
private String value="value";
public Map
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
import java.util.HashMap;
class DoubleBracesTest$1 extends HashMap {
DoubleBracesTest$1(DoubleBracesTest var1) {
this.this$0 = var1;
this.put("k", "v");
this.put(this.this$0.key, this.this$0.value);
}
}
非静态内部类的优点
改进方法
使用集合工厂的
of
方法替代
Map map = new HashMap() {{
put("k1", "v1");
put("k2", "v2");
}};
替换成:Map
List
替换成:
ListStream API 替代
List
替换成List
上一篇:线程 以及 thread类
文章标题:java踩坑记之双花括号初始化实例导致内存泄露
文章链接:http://soscw.com/index.php/essay/38447.html