黑马程序员技术交流社区

标题: 关于JAVA中的内存泄露 [打印本页]

作者: kaka小明    时间: 2013-5-1 18:37
标题: 关于JAVA中的内存泄露
GC机制能自动回收能够自动回收内存,那什么时候会产生内存泄露呢?最好举例说明产生原因及影响哈!
作者: 郭军亮    时间: 2013-5-1 19:21
内存泄露我认为是这样的:java是通过虚拟机调用操作系统的,当java中将自己的资源收走后没有关闭操作系统中的资源,导致操作系统中的资源一直开着,使得内存泄露。比如你调用了一个io方法.InputStream is=new FileInputStream("XXX.txt");这之后你并没有进行is.close();操作,这样便会造成内存泄露。。。不知道说的对不对
作者: 刘沛霞    时间: 2013-5-1 19:33
一般来说内存泄漏有两种情况。一种情况如在C/C++语言中的,在堆中的分配的内存,在没有将其释放掉的时候,就将所有能访问这块内存的方式都删掉(如指针重新赋值);另一种情况则是在内存对象明明已经不需要的时候,还仍然保留着这块内存和它的访问方式(引用)。第一种情况,在Java中已经由于垃圾回收机制的引入,得到了很好的解决。所以,Java中的内存泄漏,主要指的是第二种情况。
在不涉及复杂数据结构的一般情况下,Java的内存泄露表现为一个内存对象的生命周期超出了程序需要它的时间长度。我们有时也将其称为“对象游离”。

例如:
public class FileSearch{
2
3     private byte[] content;
4     private File mFile;
5     
6     public FileSearch(File file){
7         mFile = file;
8     }
9
10     public boolean hasString(String str){
11         int size = getFileSize(mFile);
12         content = new byte[size];
13         loadFile(mFile, content);
14         
15         String s = new String(content);
16         return s.contains(str);
17     }
18 }

在这段代码中,FileSearch类中有一个函数hasString,用来判断文档中是否含有指定的字符串。流程是先将mFile加载到内存中,然后进行判断。但是,这里的问题是,将content声明为了实例变量,而不是本地变量。于是,在此函数返回之后,内存中仍然存在整个文件的数据。而很明显,这些数据我们后续是不再需要的,这就造成了内存的无故浪费。

    要避免这种情况下的内存泄露,要求我们以C/C++的内存管理思维来管理自己分配的内存。第一,是在声明对象引用之前,明确内存对象的有效作用域。在一个函数内有效的内存对象,应该声明为local变量,与类实例生命周期相同的要声明为实例变量……以此类推。第二,在内存对象不再需要时,记得手动将其引用置空


作者: Super_Class    时间: 2013-5-1 19:34
|——JVM的回收机制具有不确定性。
      |——有时候对象使用完了,虚拟机自动调用处理机制,对象就被当做垃圾处理掉了
      |——有时候在整个过程中从未调用回收机制,就有可能造成内存没有被释放掉
|——还有一种情况就是在集合中(例如ArrayList,Vector)这个要记住那个是线程安全的,哪个是线程不安全的
new ArrayList().add(Object);
      |——假设集合中存储数据后,你更改了其中的数据(无论是值还是属性),你又通过remove()方法想要移除该对象。当然就达不到理想的效果,你所要移除的对象也不能移除掉

细心的你应该是可以看得懂的
作者: harborbest    时间: 2013-5-1 19:44
java对象的建立和放置都是在内存堆栈上面进行的。程序或者其他的对象可以锁定一块堆栈地址来进行其他对象的引用。当一个对象没有任何引用的时候,Java的自动垃圾回收机制就发挥作用,自动删除这个对象所占用的空间,释放内存以避免内存泄漏。但是内存泄漏并不是就此而完全避免了,当程序员疏忽大意地忘记解除一个对象不应该有的引用的时候,内存泄漏仍然不可避免.不过发生的几率很小。
一般出现能大量出现垃圾的是创建匿名对象时,匿名对象用完以后即成垃圾。
  1. 例:



  2. new Person(); //因为是匿名对象,没有引用句柄指向它,即为垃圾

  3. new Person().print();

  4. //当运行完匿名对象的print()方法,这个对象也变成了垃圾

  5. ……



复制代码
因此,在程序中应尽量少用匿名对象。

作者: 黄玉昆    时间: 2013-5-2 20:20
如果仍有问题,请继续追问,如果问题已解决,请将分类改为已解决,谢谢




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2