存储在磁盘上的 HashMap 从磁盘读回非常慢

jam*_*563 0 java hashmap writetofile

我有一个 HashMap 存储外部 uid,然后它存储为给定 uid 设置的不同 id(我们的应用程序的内部)。

例如:

  • 123.345.432=00001
  • 123.354.433=00002

地图由 uid 检查以确保将使用相同的内部 id。如果某些内容重新发送给应用程序。

DICOMUID2StudyIdentiferMap 定义如下:

private static Map DICOMUID2StudyIdentiferMap = Collections.synchronizedMap(new HashMap());
Run Code Online (Sandbox Code Playgroud)

但是,如果我们成功加载,加载将覆盖它,否则它将使用默认的空 HashMap。

它通过执行以下操作从磁盘读回:

FileInputStream f = new FileInputStream( studyUIDFile );  
ObjectInputStream s = new ObjectInputStream( f );

Map loadedMap = ( Map )s.readObject();
DICOMUID2StudyIdentiferMap = Collections.synchronizedMap( loadedMap );
Run Code Online (Sandbox Code Playgroud)

使用以下方法将 HashMap 写入磁盘:

FileOutputStream f = new FileOutputStream( studyUIDFile );
ObjectOutputStream s = new ObjectOutputStream( f );

s.writeObject(DICOMUID2StudyIdentiferMap);
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是,在 Eclipse 中本地运行的性能很好,但是当应用程序在机器上正常使用时,HashMap 需要几分钟才能从磁盘加载。加载后,通过查看 DICOMUID2StudyIdentiferMap.put(..., ...) 是否会返回一个值来检查以前的值也需要很长时间。

我在两种情况下都加载了相同的地图对象,它是一个 ~400kb 的文件。它包含的 HashMap 有大约 3000 个键值对。

为什么在一台机器上这么慢,而在 eclipse 中却不是?

这台机器是一台运行 XP 的虚拟机,它最近才开始变得读取 HashMap 变慢,所以它一定与它的大小有关,但是我认为 400kb 不是很大。

欢迎任何建议,TIA

Ste*_*n C 5

正如@biziclop 评论的那样,您应该首先使用分析器来查看您的应用程序的所有时间都花在哪里。

如果这没有给你任何结果,这里有一些理论。

  • 可能是您的应用程序即将耗尽堆。当 JVM 接近耗尽堆时,它几乎可以将所有时间都花在垃圾收集上,徒劳地尝试继续运行。如果您启用 GC 日志记录,这将显示。

  • 可能是 ObjectInputStream 和 ObjectOutputStream 正在执行大量小型读取系统调用。尝试用缓冲流包装文件流,看看它是否显着加快了速度。

为什么在一台机器上这么慢,而在 eclipse 中却不是?

“全堆”理论可以解释这一点。Eclipse 的默认堆大小比使用java ...没有堆大小选项启动的应用程序大得多。