内存泄漏

一个不会被使用的对象,因为另一个正在使用的对象持有该对象的引用,导致它不能正常被回收,而停留在堆内存中,从而导致内存泄漏。

最坏的情况下,由于大量的内存泄漏,最终导致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防止非静态内部类内存泄漏相关推荐

  1. java thread 内存泄露_Java ThreadLocal 内存泄露问题分析及解决方法。

    前言 在分析ThreadLocal导致的内存泄露前,需要普及了解一下内存泄露.强引用与弱引用以及GC回收机制,这样才能更好的分析为什么ThreadLocal会导致内存泄露呢?更重要的是知道该如何避免这 ...

  2. java查看内存泄露_Java内存泄露如何排查

    Java内存泄露是常常出现的问题,Java攀登网进行了该问题的整理,具体的如下所示: 1.2 内存泄露Memory Leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内 存泄露危害可以忽略 ...

  3. c++内存泄露:使用性能监视器进行内存泄露的确认

    对于服务器程序,在不停的运作中,如何去测试是否存在内存泄露,如果你的开发环境是在windows下,那么我们就可以使用windows自带的性能监视器来观察程序的性能. 使用此例子: // Test.c ...

  4. java 内存溢出 内存泄露_java 内存泄露、内存溢出、内存不足

    内存泄露 什么是内存泄露? 在维基百科上的定义如图: 中文意思就是一个对象在内存中,而程序无法获取此对象,于是不能释放该对象所占用的内存. 百度百科上的定义如图: OWASP上的定义: 开发者无法释放 ...

  5. java io内存泄露_java内存泄露和OutOfMemory

    1.内存泄露: Java的内存泄漏是指某些对象不再被应用程序使用,而垃圾收集器(Garbage Collector)却没能识别它们是"不再使用的",所以没有对这些对象进行回收,或者 ...

  6. java 解决内存泄露_Java内存泄露的理解与解决

    Java内存管理机制 在C++语言中,如果需要动态分配一块内存,程序员需要负责这块内存的整个生命周期.从申请分配.到使用.再到最后的释放.这样的过程非常灵活,但是却十分繁琐,程序员很容易由于疏忽而忘记 ...

  7. java 溢出与泄露_Java内存溢出与栈溢出

    一.背景知识 1.JVM体系结构 2.JVM运行时数据区 3.JVM内存模型 JVM运行时内存 = 共享内存区 + 线程内存区 3-1.共享内存区 共享内存区 = 持久带 + 堆 持久带 = 方法区 ...

  8. java 导致内存泄露的情况_JConsole定位内存泄漏

    在本文中,我们将看到Java中内存泄漏的示例代码.之后,我们将把Java应用程序连接到JConsole,比较有无内存泄漏时应用程序的内存使用情况.深入研究JConsole的内存监控工具可以让我们看到堆 ...

  9. java jvm内存模型_Java(JVM)内存模型– Java中的内存管理

    java jvm内存模型 Understanding JVM Memory Model, Java Memory Management are very important if you want t ...

最新文章

  1. 学python那本书比较好-Python初学者最应该读的8本书
  2. 【转载】目前为止看到描述VSCode编写C++配置文件最清楚的一篇文章
  3. 实战经验:如何定位控制文件热点块,即读取延迟高的块所在的ASM磁盘
  4. python课堂笔记之django-day02(7)
  5. easyexcel导入简单封装
  6. Tornado异步IO
  7. git 本地代码到远程库
  8. 2020网易游戏测试面试二面面经(上海春招)
  9. 计算机二级软件excel打不开怎么办,excel文件打不开的9种情况和解决办法
  10. 计算机 电脑 整机 加密,如何加密文件夹
  11. android 遥控器 地址码,RK3128平台android系统修改添加遥控器键值码值
  12. UNICODE和ANSI以及MBCS的问题
  13. samba介绍、搭建及坑
  14. PHP给PDF文件加水印(mpdf插件)
  15. 【Jquery】Jquery操作table表格详细说明
  16. Android逆向分析案例——某点评APP登陆请求数据解密
  17. 除了Navicat和DBeaver,还有没有免费又好用的数据库管理工具推荐
  18. oracle FAQ
  19. 管理 Office com 加载项
  20. java单继承和多继承

热门文章

  1. SAP ABAP OData uri type为metadata的请求处理逻辑
  2. CRM_ORGMAN_CHECK_OW
  3. SAP云平台cf push命令报错的解决方法
  4. SAP Fiori Launchpad的后台配置路径
  5. 在IE环境下用javascript触发ABAP event
  6. SAP CRM和SAP Hybris的订单日志
  7. SAP ABAP Netweaver Authorization trace tool - SAP ABAP 权限跟踪监控工具
  8. 在SAP云平台的CloudFoundry环境下消费ABAP On-Premise OData服务
  9. python练手_Python数据分析练手项目
  10. python标准库os中用来列出_Python 标准库 os 中用来列出指定文件夹中的文件和子文件夹列表的方式是listdir()。_高职高专数字资源平台答案_学小易找答案...