0

我正在尝试递归遍历我的驱动器以搜索一些文件。当文件夹/文件有限时,代码工作正常,但是当我将搜索目标定位到 C 驱动器时,我有很多文件,它会抛出堆内存不足。

线程“Thread-4”java.lang.OutOfMemoryError 中的异常:Java 堆空间

  1. 请建议我一些好的内存管理技巧,尤其是在我们进行递归调用时。
  2. 或者给我更好的方法来遍历目录而不递归。

而且我不想增加最大允许堆空间,因为这就像暂时推迟问题一样。

代码:

void iterateDirectory(String somedir) {


        File dir = new File(somedir);
        File[] files = dir.listFiles();
        if (files != null) {
            for (int id = 0; id < files.length; id++) {
                if (files[id].isDirectory() == false) 
                {
                   fsTree.add(files[id].toString()); // taking list of files
                } 
                else 
                {
                    iterateFilesInDirectory(files[id].getAbsolutePath());
                }
            }
        }
    }
4

3 回答 3

2

正如我所见,罪魁祸首是这一行:

fsTree.add(files[id].toString()); // taking list of files

您似乎将每个文件添加到全局数据结构 ( fsTree),然后在那里搜索。

我的赌注是:

A.如果您将递归函数“转换”为迭代函数,它不会消失。

B.如果不是附加到全局数据结构并最终搜索,而是在本地进行搜索/匹配,并且仅全局缓存匹配的命中,它将消失:

void iterateDirectory (String somedir, String search_term) {

    File dir = new File(somedir);
    File[] files = dir.listFiles();
    if (files != null) {
        for (int id = 0; id < files.length; id++) {
            if (files[id].isDirectory() == false) 
            {
               if (/* files[id].isDirectory() MATCHES search_term */)
                 // add to list of matching files:
                 matching_hits.add(files[id].toString());
            } 
            else 
            {
                iterateFilesInDirectory(files[id].getAbsolutePath());
            }
        }
    }
}
于 2012-05-18T15:37:44.247 回答
1

有两种可能:

  1. 您的代码中有无限递归(例如,因为您没有处理.和/或不..正确)。如果是这种情况,您必须修复代码。
  2. 您的代码确实需要比可用空间更多的堆空间。你有两个选择:
    • 减少进程的内存需求(内存分析器可以帮助您了解使用所有堆空间的内容);
    • 通过指定-XmxJVM 选项来增加堆大小。
于 2012-05-18T15:03:25.273 回答
-1

递归可以做什么是有限制的,即关于堆栈/堆的使用。请记住,无论您可以递归执行什么操作,都可以迭代执行;重写您的代码以使用迭代解决方案。

替代解决方案:有一个接口java.nio可用于递归地遍历文件系统的结构。看看这条小径,然后SimpleFileVisitor

于 2012-05-18T15:01:40.363 回答