2016-09-07 20 views
1

メモリリークの問題を修正しようとしています。ヒープダンプ解析では、ConcurrentHashMap98% of heap memoryを占有しています。コードをチェックしたところ、ConcurrentHashMapインスタンス化ではパラメータなしのコンストラクタが使用されていることが判明しました。 concurrencyLevelのデフォルトの設定は16です。このマップのインスタンス化後、私はデータがマップに置かれている同期メソッド呼び出しを見ます。同期メソッドConcurrentHashMapの同時実行レベル

私はデータが同期化されたメソッドでのみ置かれているので、concurrencyLevelをConcurrentHashMapに設定しても安全ですか?

以下はサンプルコードスニペットです:

private volatile Map<String, Integer> storeCache; 

public void someMethod() { 
    storeCache = new ConcurrentHashMap<String, Integer>(); 
    syncMethod(); 
} 

private synchronized void syncMethod() { 
    storeCache.put("Test", 1); 
} 
+0

CHMはバイト配列を使用しないため、これは何の違いもありません。デフォルトのCHMインスタンスは、バイト配列によって使用される1億バイトより少なくとも5桁少ない空間を使用します。 –

+0

私の主張:CHMは、内部に98%のスペースを占めていませんが、内部にはそれに含まれるものがあります。並列性1を使用することで何も得られません。 –

+0

アプリケーションコードでメモリリークを探す必要があります。誰かがマップにあまりにも多くのものを追加しています。マップをテキストファイルに印刷することができます。 – rghome

答えて

4
私はデータを同期する方法にのみ置かれていることから、それは安全な1へのConcurrentHashMapののconcurrencyLevelを設定することであることを知っていただきたいと思い

地図が破損しないという意味で、確かに安全です。しかし、それはあなたのメモリリークを修正するつもりはありません。実際、複数のスレッドからの安全な読み取りと書き込みをすでに保証しているConcurrentHashMapへのアクセスを同期させたくないかもしれません。外部との同期は、CHMへのシングルスレッドアクセスになります。これは、HashMapでCHMの多くの利点を排除します。​​とspecify a concurrencyLevel equal to the estimated number of concurrent writesを削除すると、パフォーマンスが大幅に向上します。

メモリリークに関しては、CHMのキーと値は強力な参照です。つまり、Javaガベージコレクタはコード内で参照されなくなったとしてもそれらを収集しません。したがって、一時的な値のキャッシュとしてCHMを使用している場合は、アプリケーションで不要になったときにCHMを.remove()にする必要があります。

(あなたは強い鍵なしのConcurrentMapのセマンティクスをしたい場合、あなたはそのアウトオブボックスを得るが、Guava provides a pretty good alternativeすることはできません。)

あなたはまた、そのキーはそのチェックすることもできます.put().equals().hashCode()を正しく実装しています。

+0

それは意味があります。丁寧な答えを書いてくれてありがとうJasonに感謝します。 –

関連する問題