当前位置: 首页 > 后端技术 > Java

Java内部类有缺陷,.100%内存泄漏!

时间:2023-04-01 17:18:24 Java

来源:https://knife.blog.csdn.net/a...今天给大家分享一个Java内部类使用不当导致的内存泄漏问题,最终导致内存溢出!希望对大家有所帮助!简介【说明】本文介绍Java内部类持有外部类导致内存泄漏的原因及解决方法。“为什么内部类持有外部类会导致内存泄漏?”非静态内部类将持有外部类。如果某个地方引用了这个非静态内部类,那么外部类也会被引用,垃圾回收时外部类是无法回收的。类(即使外部类不再在别处使用)。【解决方案】不要让其他地方持有这个非静态内部类的引用,直接在这个非静态内部类中进行业务。将非静态内部类改为静态内部类。内部类改为静态后,其引用的对象或属性也必须是静态的,所以静态内部类无法获取外部对象的引用,只能从的方法区获取静态类型引用虚拟机。为什么持有外部类在Java语言中,非静态内部类主要有两个作用:当内部类只在外部类中使用时,匿名内部类可以让外界察觉不到它的存在,从而减少代码维修工作。当内部类持有外部类时,可以直接使用外部类中的变量,调用非常方便,如下代码所示:packageorg.example.a;classOuter{privateStringouterName="Tony";内部类{私有字符串名称;publicInner(){this.name=outerName;}}内部createInner(){returnnewInner();}}publicclassDemo{publicstaticvoidmain(String[]args){Outer.Innerinner=newOuter().createInner();System.out.println(内部);但是,静态内部类不能容纳外部类及其非静态字段。另外,最新的Java面试题:https://www.javastack.cn/mst/比如下面会报错packageorg.example.a;classOuter{privateStringouterName="Tony";静态类内部{私有字符串名称;publicInner(){this.name=outerName;}}内部createInner(){returnnewInner();}}publicclassDemo{publicstaticvoidmain(String[]args){Outer.Innerinner=newOuter().createInner();System.out.println(内部);}}错误:实例:保存外部类“代码”包org.example.a;类外部{类内部{}内部创建内部(){返回新内部();}}publicclassDemo{publicstaticvoidmain(String[]args){Outer.Innerinner=newOuter().createInner();System.out.println(内部);}}》“断点调试”可以看到,内部类持有对外部类对象的引用,保存在“this$0”字段中。示例:不包含外部类“代码”包org.example.a;classOuter{staticclassInner{}InnercreateInner(){returnnewInner();}}publicclassDemo{publicstaticvoidmain(String[]args){Outer.Innerinner=newOuter().createInner();System.out.println(内部);}}更多Java教程和例子:https://github.com/javastacks/javastack《断点调试》可以发现内部类不再持有外部类。例子:内存泄漏《引言》如果内部类持有对外部类的引用,当内部类被大量使用时,会导致大量的外部类。这时候即使不使用外部类的数据,外部类的数据占用的空间也不会被释放。这个地方在外部类中存放了大量的数据,用于模拟。“代码”包org.example.a;importjava.util.ArrayList;importjava.util.List;classOuter{privateint[]data;publicOuter(intsize){this.data=newint[size];}类Innner{}InnnercreateInner(){returnnewInnner();}}publicclassDemo{publicstaticvoidmain(String[]args){Listlist=newArrayList<>();int计数器=0;while(true){list.add(newOuter(100000).createInner());System.out.println(counter++);}}}“测试”可以看到:当运行超过8000次时,内存溢出。我换成mac电脑,4000多后内存溢出了没有内存泄漏的解决办法《介绍》内部类改成static后,它所引用的对象或属性也必须是static的,所以static内部类不能获取外部对象的引用,只能从JVM的MethodArea(方法区)访问,获取静态类型的引用。“代码”包org.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<>();整数计数器=0;while(true){list.add(newOuter(100000).createInner());System.out.println(counter++);}}}“测试”可以发现:超过40万次循环溢出后没有内存。近期热点文章推荐:1.1000+Java面试题及答案(2022最新版)2.厉害了!Java协程来了。..3.SpringBoot2.x教程,太全面了!4.不要用爆破爆满画面,试试装饰者模式,这才是优雅的方式!!5.《Java开发手册(嵩山版)》最新发布,赶快下载吧!感觉不错,别忘了点赞+转发!

最新推荐
猜你喜欢