这是师弟的来信:
public class FileSearch{ private byte[] content; private File mFile; public FileSearch(File file){ mFile = file; } public boolean hasString(String str){ int size = getFileSize(mFile); content = new byte[size]; loadFile(mFile, content); String s = new String(content); return s.contains(str); } }
在这段代码中,FileSearch类中有一个函数hasString,用来判断文档中是否含有指定的字符串。流程是先将mFile加载到内存中,然后进行判断。但是,这里的问题是,将content声明为了实例变量,而不是本地变量。于是,在此函数返回之后,内存中仍然存在整个文件的数据。而很明显,这些数据我们后续是不再需要的,这就造成了内存的无故浪费。——————————我的理解——————————————conten是t实例变量不是static所以除了用到方法FileSearch时候被new出来放在堆中,其余时间因为随着方法FileSearch在栈中的消亡而消亡。。。这样真名会导致内存溢出?
这是我的回复:
首先文中的本地变量是指JAVA的局部变量,java变量有三种 :
- 类变量:类中独立于方法之外的变量,用static 修饰。
- 实例变量:类中独立于方法之外的变量,没有static修饰。
- 局部变量:类的方法中的变量。
(从你的理解中,可以看出你对JAVA的概念很不稳固),FileSearch是类不是方法,是初始化个FileSearch类,然后调用它的hasString方法来判断是否含有某个字符串。
一般调用过程是这样:
File file = newFile("c:/a.txt");
FileSearch fileSearch = new FileSearch(file);
String str = "abc";
boolean isHasABC =fileSearch.hasString(str);
我们假设(初始化)newFileSearch(file) 会在堆中开辟一块区域 称A,那么fileSearch的值就是指向A,调用hasString方法会加载a.txt的内容到内存,这段内存区域我们称为B,而content的值就是指向B。
JAVA内存泄漏需要满足两个条件:
- 这些对象的可达的,即可以调用到。(不可达的对象GC会自动回收)
- 这些对象是无用的。
建议看下这篇文章:http://app.yinxiang.com/shard/s1/sh/d0d51841-acf2-4b19-998c-925c52e404b0/046f82560c5ff2e9613fe17d0176000a
重点我已经作了标记,要理解好:GC是如何回收,什么是JAVA内存泄漏,这样你也就知道如何去避免。