Java HashMap / List替代大数据

时间:2015-10-29 06:40:05

标签: java memory hashmap

在我的Java应用程序中,我必须扫描文件系统并以递归方式存储已创建文件的路径,以便进行早期搜索。

我尝试将List / ArrayList和HashMap作为存储结构,但当文件系统包含1.000.000+文件时,内存使用量太多了。

如何在不使用一半RAM(8 GB)的情况下存储和快速检索这些“字符串”?

4 个答案:

答案 0 :(得分:1)

在全局散列映射中,您可以存储指向Dir-Objects的指针,而不是将完整路径存储为字符串。

对于您找到的每个目录,创建一个Dir-object。每个Dir-object都有一个指向其父Dir-object及其本地名称的指针。

示例:

<?=  ?>

两个子目录只需要存储对父目录的引用加上他们的本地名称“a”或“b”。

请注意,必须首先找到父对象:扫描文件系统时,应该递归执行此操作或明确使用堆栈。当你创建一个Dir-object(例如/ p)时,你将该对象推送到一个堆栈然后你访问(进入)该目录。在创建/ a和/ b sub-Dirs时,只需查看堆栈顶部即可找到其父级。完成/a/long...path/p/ is a Dir you already found. /a/long...path/p/a /a/long...path/p/b are two new Dirs 的全部内容后,弹出Dir-object,将其表示为堆栈。

答案 1 :(得分:1)

您在主存储器中存储大量字符串。无论您使用何种数据结构,它都会占用内存。一种方法可能不是始终存储整个路径,而是将它们存储在分层结构中,例如。将map中的目录名称作为键存储,并将该目录的所有值作为递归值存储在列表中。

答案 2 :(得分:0)

这个问题可以有很多答案。人们可以为您提供各种各样的数据结构,或者可能会要求您增加JVM的硬件内存或堆大小。但我认为问题出在其他地方。

仅使用基本数据结构无法解决此问题。这可能也需要在设计级别进行更改。想想你的需要。您要求的是今天的操作系统甚至是存储大量数据的RDBMS所不需要的巨大空间。

数据结构即服务。(DSAS - 它已经存在,例如redis,但是我可能已经创造了这个术语!)。

在您的应用程序设计中,尝试引入一个组件或服务,如redis,memcached或couchdb,专门用于执行“存储大量数据”,“快速搜索”而非标准套接字或其他高速通信协议(如DBUS)

不要担心此类协议的内部工作。有足够的库/ apis为你做。

答案 3 :(得分:0)

我建议您使用HashSet并将md5 sum存储为路径:

Set<Md5Sum> paths = new HashSet<>();
//for each path
String path = ...
byte[] md5 = messageDigestObject.update(path.getBytes());
path.add(new Md5Sum(md5));

您不能直接使用byte[]作为哈希集中的键。所以你需要创建简单的帮助类:

class Md5Sum{
    //it is more memory effiecient than byte[]
    long part1, part2;
    //override equals and hashCode methods
    //..........
}

关于更新

您需要重新扫描文件系统并重新创建此哈希集对象,或者您可以订阅文件系统事件(请参阅WatchService)。