Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java哈希表多访问问题_Java_Hashtable - Fatal编程技术网

Java哈希表多访问问题

Java哈希表多访问问题,java,hashtable,Java,Hashtable,我正在开发一个工具,它接受Java代码并生成代码,用于估算基本块、循环和方法的执行时间。执行某个块后,我们将其放入工具。程序模型存储在下一个表示中 static Hashtable<String, Hashtable<Integer, Hashtable<String, pair>>> method2Data = new Hashtable<String, Hashtable<Integer, Hashtable<String, pair&g

我正在开发一个工具,它接受Java代码并生成代码,用于估算基本块、循环和方法的执行时间。执行某个块后,我们将其放入工具。程序模型存储在下一个表示中

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>>();
但我还有一个问题。在每次调用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,...);
    }
for(int i=0;i
我们经常叫addBlock。 不幸的是,在我们的碎纸机上工作了一段时间后,程序就停止工作了。它看起来仍然像进程,但不占用任何cpu。我发现,如果我删除了代码,它从method2data中获取了一些东西,那么一切都没问题。所以,我猜,对哈希表的访问存在一些问题。有人有好主意吗


多亏了这一切,我似乎在并发访问的情况下出现了死锁,并且可能在没有并发操作的情况下耗尽内存

如果您使用的是Java5或更高版本,则不应使用,但是,它通过锁条带化提供了更好的可伸缩性,因此可能会立即解决问题(如果您遇到死锁或饥饿问题,这是基于您的-不完整-描述的可能性)。同样,不要使用
向量
,而是使用一些
列表
实现。
Hashtable
Vector
都是旧的集合实现,它们是同步的,在这个向量的情况下可能是不必要的

[更新]正如@finnw正确指出的那样,即使ConcurrentHashMap似乎有所帮助,您也无法确定根本原因是否真的得到了解决。需要进行彻底的分析和测试,以确定您的代码是否真正是线程安全的。如果没有看到
addBlock()
中的代码,我们就无法得出结论[/Update]


另外,正如其他人所指出的,对于大型程序来说,将配置文件数据保存在内存中不是一个好主意,因为这可能会影响您试图测量的性能特征,甚至可能会耗尽内存。

我不太了解您自行构建的配置文件机制是如何工作的。但是它看起来像是在你正在检查的程序中完成的,并且它在该程序中消耗了大量内存

顺便说一下,您在HashMap中使用了
Vector
s。向量是同步的,因此略慢于,比如说
ArrayList
s。你也许可以通过改变这一点来提高一点性能


回到主要问题上来。其他分析工具采用不同的方法:它们不构建内存中的结果数据结构,而是将所有内容记录到一个文件中。之后,一旦原始程序运行,另一个程序将读取、消化和分析日志文件。事实证明,在时间/内存使用方面,写入缓冲文件比将指令插入到程序中更加一致,干扰更少。

只是一个随机的想法:你可能内存不足了吗

尝试使用-Xmx512m启动应用程序,以允许512MB的堆空间


内存不足通常会减慢进程的速度,直到它看起来什么都不做,因为它会在每一条指令之后调用垃圾收集。

Java中的哈希表可能会触发GC中的不良行为,特别是当它们的寿命很长且很大时。HashMap也是如此。若要确定您的情况是否如此,请检查进程需要多少CPU。如果它需要大量CPU,那么GC正在运行。如果它不需要任何CPU(只是挂起),那么就会出现死锁


要查找死锁的原因,请创建一个线程转储并对其进行分析。如果您使用的是Eclipse,您可能需要查看。

它看起来很像死锁。尝试从
Hashtable
切换到
ConcurrentHashMap
,或者调查您的应用程序并添加其他锁以解决死锁问题

可以同时调用addBlock吗?如果是,是否有一些锁或同步块?是的,它们可以,但我记得哈希表是允许并发访问。这是我的第一个想法,但在恒定的工作时间内,从-Xmx2000M更改为-Xmx2500没有任何意义。另外,我查看了“top”命令,在运行程序时,有一个可用内存。这是很危险的,因为如果出现死锁,则使用
ConcurrentHashMap
会降低死锁发生的频率,从而使错误看起来是已修复的,而实际情况并非如此。@finnw,死锁可能会降低发生的频率,或者完全停止发生-如果没有看到具体的代码,这是不可能的。你是对的,这是一个风险,我更新了我的答案来澄清。谢谢你,在我想了这么多想法之后,我需要重写我代码的这一部分,并确保线程安全。
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,...);
    }