回复师弟一个关于Java内存泄漏的问题

这是师弟的来信:

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内存泄漏需要满足两个条件:
  1. 这些对象的可达的,即可以调用到。(不可达的对象GC会自动回收)
  2. 这些对象是无用的。
    文中的意思是假设fileSearch是会一直指向着A,也就是说A是一直可达,那么A是不会被回收的,里面的类变量content也就不会被回收,content指向的B满足第一个条件,hasString()的功能是检测文本中是否有一段字符串,当检测完了,内存里面的存储的a.txt的内容暂时可以说是无用的,content指向的B也满足第二个条件,所有说有内存泄漏。
建议看下这篇文章:http://app.yinxiang.com/shard/s1/sh/d0d51841-acf2-4b19-998c-925c52e404b0/046f82560c5ff2e9613fe17d0176000a
重点我已经作了标记,要理解好:GC是如何回收,什么是JAVA内存泄漏,这样你也就知道如何去避免。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值