java避免内存泄露_Java防止非静态内部类内存泄漏
内存泄漏
一个不会被使用的对象,因为另一个正在使用的对象持有该对象的引用,导致它不能正常被回收,而停留在堆内存中,从而导致内存泄漏。
最坏的情况下,由于大量的内存泄漏,最终导致jvm的内存耗尽,致使程序奔溃。也可能会导致内存空间不足,jvm出现频繁的GC。
代码示例
import java.util.ArrayList;
class OuterClass
{
private int[] data;
public OuterClass(int size)
{
data = new int[size];
}
class InnerClass
{
}
InnerClass getInnerClassObject()
{
return new InnerClass();
}
}
public class MemoryLeak
{
public static void main(String[] args)
{
ArrayList al = new ArrayList<>();
int counter = 0;
while (true)
{
al.add(new OuterClass(100000).getInnerClassObject());
System.out.println(counter++);
}
}
}
执行以上代码,输出结果,最终导致了堆内存溢出。
7639
7640
7641
7642
7643
7644
7645
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at EnclosingClass.(MemoryLeak.java:9)
at MemoryLeak.main(MemoryLeak.java:30)
原因分析
我们使用java提供的工具javap,可以对编译生成的.class文件做分析。也可以使用一些反编译工具对生成的.class反编译,也可以看到内部类的代码实现。
javap OuterClass$InnerClass
输出类似于:
Compiled from "OuterClass.java"
public class OuterClass$InnerClass {
final OuterClass this$0;
public OuterClass$InnerClass(OuterClass);
}
可以看到内部类InnerClass存在一个this$0的OuterClass的变量,此变量是通过InnerClass的构造函数传进来的。
示例代码中创建了一个数组列表ArrayList,它将用来存放InnerClass的对象。生成InnerClass对象前,需要先构造OuterClass。OuterClass构造时默认创建了一个100000大小的整型数组。相当于一个初始化的OuterClass默认占用10000个int整型的空间。在MemoryLeak,通过循环while不断向a1添加InnerClass对象。对于每次循环来说new OuterClass后,就不会再使用OuterClass对象。但通过分析内部了的实现,即使OuterClass对象不会再被使用,内部类InnerClass对象里还是保存了大对象OuterClass,导致OuterClass的生命周期是和InnerClass一样,最终导致内存泄漏。
非静态内部类使用注意
1、如果外部类是一个大对象,必须要谨慎使用非静态内部类,特别时生命周期长的非静态内部类,这样容易造成内存溢出OutOfMemoryError。
2、之所以强调非静态,对于静态内部类来说,它的内部实现是不存放外部类的,所以再合理编码的情况下,使用静态内部类。
java避免内存泄露_Java防止非静态内部类内存泄漏相关推荐
- java thread 内存泄露_Java ThreadLocal 内存泄露问题分析及解决方法。
前言 在分析ThreadLocal导致的内存泄露前,需要普及了解一下内存泄露.强引用与弱引用以及GC回收机制,这样才能更好的分析为什么ThreadLocal会导致内存泄露呢?更重要的是知道该如何避免这 ...
- java查看内存泄露_Java内存泄露如何排查
Java内存泄露是常常出现的问题,Java攀登网进行了该问题的整理,具体的如下所示: 1.2 内存泄露Memory Leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内 存泄露危害可以忽略 ...
- c++内存泄露:使用性能监视器进行内存泄露的确认
对于服务器程序,在不停的运作中,如何去测试是否存在内存泄露,如果你的开发环境是在windows下,那么我们就可以使用windows自带的性能监视器来观察程序的性能. 使用此例子: // Test.c ...
- java 内存溢出 内存泄露_java 内存泄露、内存溢出、内存不足
内存泄露 什么是内存泄露? 在维基百科上的定义如图: 中文意思就是一个对象在内存中,而程序无法获取此对象,于是不能释放该对象所占用的内存. 百度百科上的定义如图: OWASP上的定义: 开发者无法释放 ...
- java io内存泄露_java内存泄露和OutOfMemory
1.内存泄露: Java的内存泄漏是指某些对象不再被应用程序使用,而垃圾收集器(Garbage Collector)却没能识别它们是"不再使用的",所以没有对这些对象进行回收,或者 ...
- java 解决内存泄露_Java内存泄露的理解与解决
Java内存管理机制 在C++语言中,如果需要动态分配一块内存,程序员需要负责这块内存的整个生命周期.从申请分配.到使用.再到最后的释放.这样的过程非常灵活,但是却十分繁琐,程序员很容易由于疏忽而忘记 ...
- java 溢出与泄露_Java内存溢出与栈溢出
一.背景知识 1.JVM体系结构 2.JVM运行时数据区 3.JVM内存模型 JVM运行时内存 = 共享内存区 + 线程内存区 3-1.共享内存区 共享内存区 = 持久带 + 堆 持久带 = 方法区 ...
- java 导致内存泄露的情况_JConsole定位内存泄漏
在本文中,我们将看到Java中内存泄漏的示例代码.之后,我们将把Java应用程序连接到JConsole,比较有无内存泄漏时应用程序的内存使用情况.深入研究JConsole的内存监控工具可以让我们看到堆 ...
- java jvm内存模型_Java(JVM)内存模型– Java中的内存管理
java jvm内存模型 Understanding JVM Memory Model, Java Memory Management are very important if you want t ...
最新文章
- 学python那本书比较好-Python初学者最应该读的8本书
- 【转载】目前为止看到描述VSCode编写C++配置文件最清楚的一篇文章
- 实战经验:如何定位控制文件热点块,即读取延迟高的块所在的ASM磁盘
- python课堂笔记之django-day02(7)
- easyexcel导入简单封装
- Tornado异步IO
- git 本地代码到远程库
- 2020网易游戏测试面试二面面经(上海春招)
- 计算机二级软件excel打不开怎么办,excel文件打不开的9种情况和解决办法
- 计算机 电脑 整机 加密,如何加密文件夹
- android 遥控器 地址码,RK3128平台android系统修改添加遥控器键值码值
- UNICODE和ANSI以及MBCS的问题
- samba介绍、搭建及坑
- PHP给PDF文件加水印(mpdf插件)
- 【Jquery】Jquery操作table表格详细说明
- Android逆向分析案例——某点评APP登陆请求数据解密
- 除了Navicat和DBeaver,还有没有免费又好用的数据库管理工具推荐
- oracle FAQ
- 管理 Office com 加载项
- java单继承和多继承
热门文章
- SAP ABAP OData uri type为metadata的请求处理逻辑
- CRM_ORGMAN_CHECK_OW
- SAP云平台cf push命令报错的解决方法
- SAP Fiori Launchpad的后台配置路径
- 在IE环境下用javascript触发ABAP event
- SAP CRM和SAP Hybris的订单日志
- SAP ABAP Netweaver Authorization trace tool - SAP ABAP 权限跟踪监控工具
- 在SAP云平台的CloudFoundry环境下消费ABAP On-Premise OData服务
- python练手_Python数据分析练手项目
- python标准库os中用来列出_Python 标准库 os 中用来列出指定文件夹中的文件和子文件夹列表的方式是listdir()。_高职高专数字资源平台答案_学小易找答案...