简述Java内存泄露

简介: 翻译人员: 铁锚翻译时间: 2013年11月4日原文链接: The Introduction of Memory Leaks内存管理一直是Java 所鼓吹的强大优点。开发者只需要简单地创建对象,而Java的垃圾收集器将会自动管理内存空间的分配和释放.但在很多情况下,事情并不那么简单,在 Java程序中总是会频繁地发生内存泄露(Memory Leaks).本文阐述什么是内存泄露,为什么会泄露,以及如何防止内存泄露。
翻译人员: 铁锚
翻译时间: 2013年11月4日
原文链接: The Introduction of Memory Leaks

内存管理一直是Java 所鼓吹的强大优点。开发者只需要简单地创建对象,而Java的垃圾收集器将会自动管理内存空间的分配和释放.但在很多情况下,事情并不那么简单,在 Java程序中总是会频繁地发生内存泄露(Memory Leaks).
本文阐述什么是内存泄露,为什么会泄露,以及如何防止内存泄露。

内存泄露是什么?
内存泄露的定义: 当某些对象不再被应用程序所使用,但是由于仍然被引用而导致垃圾收集器不能释放(Remove,移除)他们.
用白话来说就是: 该回收的内存没被回收,最后因为内存不够用而导致程序报错。

要理解这个定义,我们需要理解内存中的对象状态. 下图展示了什么是不使用的部分,以及未被引用的部分。


图1

从图中可以看出,内存中存在着 有引用的对象,和无引用的对象. 无引用的对象将被垃圾收集器所回收,而有引用的对象则不会被当做垃圾收集. 因为没有任何其他对象所引用,所以无引用对象一定是不再使用的。 但是有一部分无用对象仍然被(无意中)引用着。这就是发生内存泄露的根源.

为什么内存会泄露?
让我们看下面的实例来了解为什么内存会泄露. 在下面的情境中,对象A引用了对象B. A的生命周期(t1 - t4) 比 B的(t2 - t3)要长得多. 当对象B在应用程序逻辑中不会再被使用以后, 对象 A 仍然持有着 B的引用. (根据虚拟机规范)在这种情况下垃圾收集器不能将 B 从内存中释放. 这种情况很可能会引起内存问题,假若A 还持有着其他对象的引用,那么这些被引用的(无用)对象都不会被回收,并占用着内存空间.
甚至有可能 B 也持有一大堆其他对象的引用。 这些对象由于被 B 所引用,也不会被垃圾收集器所回收. 所有这些无用的对象将消耗大量宝贵的内存空间。

图2

怎么防止内存泄露?
要防止内存泄露,下面是一些快速上手的实用技巧:
1. 当心集合类,比如 HashMap,ArrayList等,因为这是最容易发生内存泄露的地方.当集合对象被声明为static时,他们的生命周期一般和整个应用程序一样长。
2. 注意事件监听和回调.当注册的监听器不再使用以后,如果没有被注销,那么很可能会发生内存泄露.
3. "当一个类自己管理其内存空间时,程序员应该注意内存泄露." 常常是一个对象的成员变量需要被置为null 时仍然指向其他对象,

一个小测验: 为什么 JDK6 中的 substring() 方法有可能导致内存泄露?
要回答这个问题,请参考:  JDK6和JDK7中String的substring()方法及其差异

参考资料:
[1] Bloch, Joshua. Effective java. Addison-Wesley Professional, 2008.
[2] IBM Developer Work. http://www.ibm.com/developerworks/library/j-leaks/

相关文章:
1.  

Java 对象在堆中的内存结构


2.   Java 数组在内存中的结构
3. How is an array stored in memory and brought to cache?
4.  Java String 常见问题

目录
相关文章
|
6天前
|
存储 分布式计算 监控
Java一分钟之-Hazelcast:内存数据网格
【6月更文挑战第17天】**Hazelcast是开源的内存数据网格(IMDG),加速分布式环境中的数据访问,提供内存存储、分布式计算、线性扩展及高可用性。常见挑战包括内存管理、网络分区和数据分布不均。通过配置内存限制、优化网络和分区策略可避免问题。示例展示如何创建Hazelcast实例并使用分布式Map。使用Hazelcast提升性能和扩展性,关键在于理解和调优。**
21 1
|
11天前
|
存储 缓存 Java
Java内存模型
Java内存模型
12 0
|
2天前
|
Java 机器人 数据库连接
Java中的内存泄漏问题解析与应对
Java中的内存泄漏问题解析与应对
|
1天前
|
存储 缓存 Java
Java中的缓冲流提升I/O性能,通过内存缓冲区减少对硬件访问
【6月更文挑战第22天】Java中的缓冲流提升I/O性能,通过内存缓冲区减少对硬件访问。`BufferedInputStream`和`BufferedOutputStream`用于字节流,缓存数据批量读写。`BufferedReader`和`BufferedWriter`处理字符流,支持按行操作。使用后务必关闭流。
9 3
|
3天前
|
监控 算法 Java
Java虚拟机(JVM)使用多种垃圾回收算法来管理内存,以确保程序运行时不会因为内存不足而崩溃。
【6月更文挑战第20天】Java JVM运用多种GC算法,如标记-清除、复制、标记-压缩、分代收集、增量收集、并行收集和并发标记,以自动化内存管理,防止因内存耗尽导致的程序崩溃。这些算法各有优劣,适应不同的性能和资源需求。垃圾回收旨在避免手动内存管理,简化编程。当遇到内存泄漏,可以借助VisualVM、JConsole或MAT等工具监测内存、生成堆转储,分析引用链并定位泄漏源,从而解决问题。
12 4
|
2天前
|
存储 缓存 Java
并发编程-Java内存模型到底是什么
并发编程-Java内存模型到底是什么
|
3天前
|
安全 Java 开发者
深入理解Java内存模型(JMM)及其对并发编程的影响
【6月更文挑战第19天】在Java的世界中,内存模型是构建高效、线程安全应用的基石。本文将通过探讨Java内存模型(JMM)的核心概念和原理,揭示它如何影响并发编程实践。我们将从JMM的基本定义出发,逐步解析它在同步机制、可见性规则以及有序性保证方面的作用。同时,我们也将讨论JMM对现代Java开发中常见的并发模式和框架的影响。最后,文章会提供一些实际的编码建议和最佳实践,帮助开发者更好地利用JMM来设计并发程序。
|
5天前
|
算法 Java
Java垃圾回收(Garbage Collection,GC)是Java虚拟机(JVM)的一种自动内存管理机制,用于在运行时自动回收不再使用的对象所占的内存空间
【6月更文挑战第18天】Java的GC自动回收内存,包括标记清除(产生碎片)、复制(效率低)、标记整理(兼顾连续性与效率)和分代收集(区分新生代和老年代,用不同算法优化)等策略。现代JVM通常采用分代收集,以平衡性能和内存利用率。
31 3
|
4天前
|
存储 监控 Java
Java内存管理:深入理解垃圾收集器
在Java的世界中,内存管理是程序高效运行的基石。本文将揭开Java内存管理的神秘面纱,着重探讨其核心机制——垃圾收集器。我们将从基础原理出发,逐步深入到不同垃圾收集器的工作原理和适用场景,最后通过实际案例分析,帮助读者更好地理解和应用垃圾收集器,提升Java应用程序的性能与稳定性。
|
6天前
|
缓存 监控 算法
【Java】Java内存溢出:原因、预防和解决方法
【Java】Java内存溢出:原因、预防和解决方法
13 2