我正在开发工具,它采用 Java 代码并生成代码来估计基本 block 、循环和方法的执行时间。执行某个 block 后,我们将时间交给我们的工具。程序模型存储在下一个表示中
static Hashtable<String, Hashtable<Integer, Hashtable<String, pair>>> method2Data = new Hashtable<String, Hashtable<Integer, Hashtable<String, pair>>>();
static Hashtable<String, Vector<String>> class2Method = new Hashtable<String, Vector<String>>();
以及通过方法放置的时间
public static void addBlock(int id, double time, String meth, String thread);
但是我有下一个问题。每次调用 addBlock 时,我们都会从 method2data 中获取一些内容。因为我们可以有这样的代码
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
for (int k = 0; k < n; k++) {
addBlock(0,...);
addBlock(m,...);
}
我们多次调用addBlock。 不幸的是,在我们的集群上持续工作一段时间后,程序就停止工作了。它看起来仍然像进程,但不占用任何CPU。我发现,如果我删除从 method2data 获取某些内容的代码,那么一切都可以。所以,我猜想,访问哈希表存在一些问题。大家有什么好主意吗?
感谢所有人,看来我在并发访问的情况下遇到了死锁,并且当没有并发事物时可能会耗尽内存。
最佳答案
如果您使用的是 Java5 或更高版本,则不应使用 Hashtable
,但是ConcurrentHashMap
,它通过锁 strip 提供了更好的可扩展性,因此可能会立即解决问题(如果您遇到死锁或饥饿问题,这是基于您的 - 不完整 - 描述的可能性)。在同一行中,不要使用 Vector
,而是使用一些 List
实现。 Hashtable
和 Vector
都是旧的集合实现,它们是同步的,在此 Vector 的情况下可能没有必要。
[更新] 正如 @finnw 正确指出的那样,即使 ConcurrentHashMap 似乎有帮助,您也不能确定根本原因是否真正得到解决。需要进行彻底的分析和测试才能确定您的代码是否真正是线程安全的。如果没有看到 addBlock()
中的代码,我们无法得出结论。 [/更新]
此外,正如其他人指出的那样,对于大型程序来说,将配置文件数据保存在内存中并不是一个好主意,因为这可能会影响您尝试测量的性能特征,甚至可能会耗尽内存。
关于Java Hashtable多次访问问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3235297/