文档章节

Java内存泄露介绍

爱兔一生
 爱兔一生
发布于 2017/03/23 14:46
字数 687
阅读 28
收藏 2

Java的最显着的优点之一是其内存管理。您只需创建对象,并且Java Garbage Collector负责分配和释放内存。但是,情况并不那么简单,因为Java应用程序中经常发生内存泄漏。

本教程将说明什么是内存泄漏,为什么会这样发生,以及如何防止它们。

1.什么是内存泄漏?

内存泄漏的定义:应用程序不再使用对象,但垃圾收集器无法将其删除,因为它们被引用。

要理解这个定义,我们需要了解内存中的对象状态。下图说明了什么是未使用的,什么是未引用的。

内存泄露

从图中可以看到引用的对象和未引用的对象。未引用的对象将被垃圾回收,而引用对象不会被垃圾回收。未引用的对象肯定是未使用的,因为没有其他对象引用它。但是,未使用的对象并不全部未被引用。其中一些被引用!这就是内存泄漏的地方。

###2.为什么会出现内存泄漏?

我们来看看下面的例子,看看为什么会出现内存泄漏。在下面的例子中,对象A引用对象B.A的生存期(t1-t4)比B(t2-t3)长得多。当B在应用程序中不再被使用时,A仍然保留对它的引用。这样垃圾收集器就不能从内存中删除B。这可能会导致内存不足的问题,因为如果A对于更多的对象执行相同的操作,那么会有很多未被收集的对象消耗内存空间。

B也可能存在一堆其他对象的引用。 B引用的对象也不会被收集。所有这些未使用的对象将消耗宝贵的内存空间。

对象示意

###3.如何防止内存泄漏?

以下是一些用于防止内存泄漏的快速实用技巧。

  1. 注意集合类,如HashMap,ArrayList等,因为它们是找到内存泄漏的常见位置。当它们被声明为静态时,其使用寿命与应用程序的使用寿命相同。

  2. 注意事件侦听器和回调。如果在不再使用该类的情况下监听器注册但未注册,则可能会发生内存泄漏。

  3. “如果一个类管理自己的内存,程序员应该警告内存泄漏。”[1]通常,指向其他对象的对象的成员变量需要为空。

  4. 一个小问题:为什么在JDK 6中的substring()方法可能会导致内存泄漏?

要回答这个问题,看这篇文章

© 著作权归作者所有

爱兔一生
粉丝 12
博文 18
码字总数 11362
作品 0
常州
高级程序员
私信 提问
在 JNI 编程中避免内存泄漏

此文转自 IBM developerWorks JNI 编程简介 JNI,Java Native Interface,是 native code 的编程接口。JNI 使 Java 代码程序可以与 native code 交互——在 Java 程序中调用 native code;在...

IBMdW
2011/04/26
995
1
out就可以理解为System类的静态成员变量引用了PrintStream类的对象

面试题是实验室师兄面试提供的。两道题 题1:Java中System.out.print()如何理解? 查阅API文档,我们可以知道:System是Java中的一个类,而out是System类的成员 。 out属于java.io.PrintStre...

变小火
2018/06/29
0
0
JVM第一篇:一个Java内存泄漏的排查案例

最近在看《深入理解Java虚拟机:JVM高级特性与最佳实践》(第二版)这本书,理论+实践结合,深入浅出,强烈推荐给大家。 这两天在“小怪的java群”里面也对JVM内容进行了一个讨论,讨论的内容...

小怪聊职场
2018/05/31
0
0
ThreadLocal可能引起的内存泄露

  threadlocal里面使用了一个存在弱引用的map,当释放掉threadlocal的强引用以后,map里面的value却没有被回收.而这块value永远不会被访问到了. 所以存在着内存泄露. 最好的做法是将调用thr...

天天顺利
2018/06/15
76
0
多线程并发神器--ThreadLocal

什么是ThreadLocal 可以理解成线程本地变量,传统的线程对一个变量操作时操作的是同一个对象,也存在线程安全的问题。 ThreadLocal是一个变量的本地副本,线程对变量的操作不会影响其他线程。...

java技术栈
2017/08/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

PostgreSQL 11.3 locking

rudi
今天
5
0
Mybatis Plus sql注入器

一、继承AbstractMethod /** * @author beth * @data 2019-10-23 20:39 */public class DeleteAllMethod extends AbstractMethod { @Override public MappedStatement injectMap......

一个yuanbeth
今天
10
1
一次写shell脚本的经历记录——特殊字符惹的祸

本文首发于微信公众号“我的小碗汤”,扫码文末二维码即可关注,欢迎一起交流! redis在容器化的过程中,涉及到纵向扩pod实例cpu、内存以及redis实例的maxmemory值,statefulset管理的pod需要...

码农实战
今天
4
0
为什么阿里巴巴Java开发手册中不建议在循环体中使用+进行字符串拼接?

之前在阅读《阿里巴巴Java开发手册》时,发现有一条是关于循环体中字符串拼接的建议,具体内容如下: 那么我们首先来用例子来看看在循环体中用 + 或者用 StringBuilder 进行字符串拼接的效率...

武培轩
今天
8
0
队列-链式(c/c++实现)

队列是在线性表功能稍作修改形成的,在生活中排队是不能插队的吧,先排队先得到对待,慢来得排在最后面,这样来就形成了”先进先出“的队列。作用就是通过伟大的程序员来实现算法解决现实生活...

白客C
今天
81
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部