2


0

Java Hashtableの多アクセス問題

私はJavaコードを受け取り、基本ブロック、ループ、およびメソッドの実行時間の推定値を取得するためのコードを生成するツールを開発しています。 いくつかのブロックが実行された後、今度はツールに入力します。 プログラムモデルは次の表現で保存されます

static Hashtable>> method2Data = new Hashtable>>();

static Hashtable> class2Method = new Hashtable>();

そして、メソッドによって入れられた時間

 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_から何かを取得するコードを削除すれば、すべて問題ないことがわかりました。 それで、Hashtableへのアクセスに問題があると思います。 誰か良いアイデアがありますか?

すべてのおかげで、同時アクセスの場合にデッドロックが発生しているようであり、同時アクセスがない場合はおそらくメモリ不足になる可能性があります。

5 Answer


3


Java5以上を使用している場合、http://download.oracle.com/docs/cd/E17476_01/javase/1.4.2/docs/api/java/util/Hashtable.html [Hashtable`を使用しないでください。 ]、ただしhttp://cupi2.uniandes.edu.co/~cupi2/sitio/images/recursos/javadoc/j2se/1.5.0/docs/api/java/util/concurrent/ConcurrentHashMap.html [`ConcurrentHashMap] 、ロックストライピングを介してはるかに優れたスケーラビリティを提供するため、問題を即座に解決する可能性があります(デッドロックまたは飢vの問題がある場合、これは-不完全-説明に基づく可能性があります)。 そして同じ行で、 Vector`を使用せず、代わりに List`実装を使用します。 Hashtable`と Vector`は両方とも古いコレクションの実装であり、このベクターの場合は不必要に同期される可能性があります。

  • [更新] * @finnwが正しく指摘したように、ConcurrentHashMapが_seems_を助けても、根本的な原因が本当に解決されたかどうかはわかりません。 コードが実際にスレッドセーフかどうかを確認するには、徹底的な分析とテストが必要です。 `addBlock()`のコードを見なければ、これを結論付けることはできません。 [/更新]

また、他の人が指摘したように、プロファイルデータをメモリに保持することは、測定しようとしているパフォーマンス特性に影響を与える可能性があり、メモリ不足になる可能性があるため、大規模なプログラムには適していません。


3


ただのランダムな考え:あなたはおそらくメモリを使い果たしましたか?

-Xmx512mを使用してアプリケーションを起動し、512 MBのヒープスペースを確保してください。

通常、メモリが不足すると、他のすべての命令の後にガベージコレクションを呼び出しているため、何もしないように見えるまでプロセスの速度が低下します。


3


Javaのハッシュテーブルは、特に長寿命で大きな場合、GCで厄介な動作を引き起こす可能性があります。 HashMapについても同様です。 これが当てはまるかどうかを判断するには、プロセスに必要なCPUの量を確認します。 大量のCPUが必要な場合は、GCが実行されています。 CPUを必要としない(ハングする)場合、デッドロックが発生します。

デッドロックの原因を見つけるには、スレッドダンプを作成して分析します。 Eclipseを使用している場合、http://lockness.plugin.free.fr/home.php [Lockness]をご覧ください。


1


自作のプロファイリングメカニズムがどのように機能しているか、私にはよくわかりません。 しかし、あなたがチェックしているプログラム内で行われているように見え、そのプログラム内で多くのメモリを消費しています。

余談ですが、そのHashMapで `Vector`を使用しています。 ベクトルは同期されているため、たとえば「ArrayList」よりもやや遅くなります。 おそらく、それを変更することでわずかなパフォーマンスを引き出すことができます。

主な問題に戻ります。 他のプロファイリングツールは異なるアプローチを採用しています。結果のメモリ内データ構造を構築するのではなく、すべてをファイルに記録します。 後で、元のプログラムが実行されると、別のプログラムがログファイルを読み取り、ダイジェストして分析します。 バッファされたファイルへの書き込みは、プログラムをプログラムに移植するよりも、時間/メモリ使用量に関して一貫性があり、邪魔になりません。


-1


デッドロックのように見えます。 Hashtable`から ConcurrentHashMap`に切り替えるか、アプリケーションを調査して、ロックを追加してデッドロックを解決してください。