--Java中会存在内存泄露吗?

--如果你想当然的以为Java里有了垃圾回收机制就不会存在内存泄露,那你就错了。

Java里也会存在内存泄露!

我们慢慢来分析。

所谓内存泄露就是指一个不再被程序使用的对象一直占据在内存中。Java中有内存回收机制,他可以保证一对象不再被引用的时候,即对象变成了孤儿的时候,对象将自动被垃圾回收机制从内存中清楚掉。

由于Java使用有向图的方式进行垃圾回收管理,可以消除引用循环的问题,即例如有两个对象相互引用,只要他们和根进程不可达,那么GC也会回收他们的。

关于Java中出现的内存泄露的情况:

长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有他的引用而导致不能被回收,这就是Java中内存泄露发生的场景。

通俗的说,就是程序员可能创建了一个对象,以后一直不再使用这个对象,这个对象却一直被引用,即这个对象无用但是却无法被垃圾回收器回收。

例如缓存系统,我们加载了一个对象放在缓存中(例如放在一个全局map对象中),然后一直不再使用他,这个对象会一直被缓存引用,但却不再被使用。

如果一个外部类的实例对象的方法返回了一个内部类的实例对象,这个内部类对象被长期引用了,即使那个外部类实例对象不再被使用,但由于内部类持有外部类的实例对象,这个外部类对象将不会被垃圾回收,也会造成内存泄露。

下面是一个堆栈的经典的例子:

public class Stack {
private Object[] elements = new Object[10]; private int size = 0; public void push(Object e){
ensureCapacity();
elements[size++] = e;
} public Object pop(){
if(size == 0){
throw new EmptyStackException();
}
return elements[--size];
} private void ensureCapacity(){
if(elements.length == size){
Object[] oldElements = elements;
elements = new Object[2 * elements.length + 1];
System.arraycopy(oldElements, 0, elements, 0, size);
}
}
}

上面的代码很简单,假如堆栈加了10个元素,然后全部弹出来,虽然堆栈是空的,没有我们要的东西,但是这个对象是无法回收的。

这个才符合了内存泄露的两个条件:无用,无法回收。

但是,存在这样的东西也不一定会导致什么样的后果,如果这个堆栈用的比较少,也就浪费了几个K的内存而已,反正我们的内存都上G了,哪有会有什么影响。再说这个东西很快就会被回收的,关系不大。

再看下面这个例子:

class Bad{
public static Stack s = new Stack();
static{
s.push(new Object());
s.pop(); //这里有一个对象发生内存泄露了!
s.push(new Object()); //上面的对象可以被回收了,等于是自愈了。
}
}

因为是static,就一直存在到程序退出,但是我们也可以看到他有自愈功能,就是说如果你的Stack最多有100个对象,那么最后也就只有100个对象无法被回收。Stack持有100个引用,最坏的情况下就是他们都是无用的,因为我们一旦放进新的,以前的引用自然消失了。

内存泄露的另外一种情况:

当一个对象被存储进HashSet集合中以后,就不能修改这个对象中的那些参与计算hash值的字段了,否则,对象修改后的hash值与最初存储进HashSet集合中时的hash值就不同了,在这种情况下,即使contains方法使用该对象的当前引用作为参数去HashSet集合中检索对象也将返回找不到对象的结果,这也会导致无法从HashSet集合中单独删除当前对象,造成内存泄露。

Java宝典(四)------Java中也存在内存泄露。的更多相关文章

  1. iPhone应用中如何避免内存泄露?

    如何有效控制iPhone内存管理的对象的所有权与引用计数和以及iPhone内存的自动释放与便捷方法.本文将介绍在iPhone应用中如何避免内存泄露.想了解“在iPhone应用中如何避免内存泄露”就必须 ...

  2. 对开发中常见的内存泄露,GDI泄露进行检测

    对开发中常见的内存泄露,GDI泄露进行检测 一.GDI泄露检测方法: 在软件测试阶段,可以通过procexp.exe 工具,或是通过任务管理器中选择GDI对象来查看软件GDI的对象是使用情况. 注意点 ...

  3. java: web应用中不经意的内存泄露

    前面有一篇讲解如何在spring mvc web应用中一启动就执行某些逻辑,今天无意发现如果使用不当,很容易引起内存泄露,测试代码如下: 1.定义一个类App package com.cnblogs. ...

  4. JAVA中会存在内存泄露吗

    所谓内存泄露就是指一个不再被程序使用的对象或变量一直被占据在内存中.java中有垃圾回收机制,它可以保证一对象不再被引用的时候,即对象编程了孤儿的时候,对象将自动被垃圾回收器从内存中清除掉.由于Jav ...

  5. Java中会有内存泄露吗?

    一.Java内存回收机制 不论哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址.Java中对象是采用new或者反射的方法创建的, 这些对象的创建都是在堆(He ...

  6. Java中会存在内存泄露吗?请简单描述。

    本文转载自:Java中会存在内存泄漏吗,请简单描述 会.java导致内存泄露的原因很明确:长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周 ...

  7. java中常见的内存泄露的例子

    JAVA 中的内存泄露     Java中的内存泄露,广义并通俗的说,就是:不再会被使用的对象的内存不能被回收,就是内存泄露.     Java中的内存泄露与C++中的表现有所不同.     在C++ ...

  8. java程序——CPU过高100%及内存泄露排查

    CPU过高 这类问题可以使用 top 命令观察一些,CPU 是不是都被 Java 程序占用了.比如下面这个截图: 服务器的 CPU 大多都被 Java 占用了.这正是我们之前生产上 CPU 过高的一个 ...

  9. Java技术专题之JVM你的内存泄露了吗?

    一.从一个例子开始 关于JVM的内存泄露,让我们从下面一个例子开始吧,大家来判断一下如果按照下面这种分配方式,会不会出现内存泄露呢? import java.util.List; import jav ...

随机推荐

  1. 线性时间构造普吕弗(Prüfer)序列

    tree -> sequence 首先预处理数组 deg[N], deg[i]表示编号为i的节点的度数,我们每次要删除的节点肯定是 满足deg[i]=1 的编号最小节点, 首先找到所有叶子并选出 ...

  2. IT English Collection(9) of Objective-C

    1 前言 今天我们来解除一篇有关Objective-C的介绍文章,详情如下. 2 详述 2.1 原文 Objective-C defines a small but powerful set of e ...

  3. 在Ubuntu上下载、编译和安装Android最新内核源代码(Linux Kernel)

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6564592 在前一篇文章提到,从源代码树下载下 ...

  4. .NET基础拾遗(3)字符串、集合和流1

    一.字符串处理 1.1 StringBuilder类型 众所周知,在.NET中String是引用类型,具有不可变性,当一个String对象被修改.插入.连接.截断时,新的String对象就将被分配,这 ...

  5. Javascript基础form表单

    <!DOCTYPE HTML> <html> <head> <script type="text/javascript" charset= ...

  6. IEquatable(T) interface in .Net

    原文:http://weblogs.asp.net/pawanmishra/iequatable-t-interface-in-net 泛型方法: public static bool AreEqua ...

  7. repeater截取字数

    <%# Eval("ArticleName").ToString().Length > 14 ? Eval("ArticleName").ToStr ...

  8. Android-图标

    首先需要申明一点,系统图标并不存在于项目资源中,而是存在于设备中. 这就带来一个大问题,界面风格的控制权交到了不同的设备手中.这是我们不愿意看到的. 如何解决这个问题?有两种方法: 1.创建自己的图标 ...

  9. DataTable转json字符串,jQuery.parseJSON()把json字符串转为标准的json对象格式

    1.string res = DataTableToJson.DataTable2Json(dt);讲DataTable转换为json字符串 http://www.365mini.com/page/j ...

  10. 16 Socket通信(简单例子)

      服务端代码: import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.Da ...