简体   繁体   English

同步方法中ConcurrentHashMap的并发级别

[英]Concurrency level for ConcurrentHashMap in synchronized method

I'm trying to fix a memory leak issue. 我正在尝试解决内存泄漏问题。 Heap dump analysis shows that a ConcurrentHashMap is occupying around 98% of heap memory . 堆转储分析表明, ConcurrentHashMap占据了大约98% of heap memory Checked the code and it turns out that ConcurrentHashMap instantiation is using a constructor with no parameter. 检查了代码,结果发现ConcurrentHashMap实例化使用的是没有参数的构造函数。 The default configuration for concurrencyLevel is 16. After this map instantiation I see a synchronized method call where data is being put in the map. concurrencyLevel的默认配置为16。在此映射实例化之后,我看到一个同步方法调用,其中将数据放入映射中。

I would like to know that since data is being put only in synchronized method, is it safe to set concurrencyLevel of ConcurrentHashMap to 1? 我想知道,由于仅将数据放入同步方法中,因此将ConcurrentHashMap concurrencyLevel设置为1是否安全?

Following is the sample code snippet: 以下是示例代码片段:

private volatile Map<String, Integer> storeCache;

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

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

I would like to know that since data is being put only in synchronized method, is it safe to set concurrencyLevel of ConcurrentHashMap to 1? 我想知道,由于仅将数据放入同步方法中,因此将ConcurrentHashMap的concurrencyLevel设置为1是否安全?

It's certainly safe, in the sense that it's not going to cause any Map corruption. 从某种意义上讲,这不会造成地图损坏,从某种意义上讲,它是安全的。 However, it's not going to fix your memory leak. 但是,它不能解决您的内存泄漏问题。 In fact, you probably don't want to synchronize access to the ConcurrentHashMap, which already guarantees safe reads and writes from multiple threads. 实际上,您可能不想同步对ConcurrentHashMap的访问,该访问已保证可以安全地从多个线程进行读写。 Synchronizing externally is going to single-thread access to your CHM, which is going to eliminate many of the benefits of the CHM over a HashMap. 从外部进行同步将对CHM进行单线程访问,这将消除CHM与HashMap相比的许多优点。 If you remove the synchronized and specify a concurrencyLevel equal to the estimated number of concurrent writes , you'll probably achieve much better performance. 如果删除synchronized指定等于并发写入的估计数量的concurrencyLevel ,则可能会获得更好的性能。

As for your memory leak, the keys and values in the CHM are strong references, meaning the Java garbage collector won't collect them, even if they're no longer referenced anywhere else in your code. 至于您的内存泄漏,CHM中的键和值是强引用,这意味着Java垃圾收集器不会收集它们,即使它们在代码中的其他任何地方都不再被引用。 So if you're using the CHM as a cache for temporary values, you'll need to .remove() them when your application no longer needs them. 因此,如果您将CHM用作临时值的缓存,则当您的应用程序不再需要它们时,需要对它们进行.remove()

(If you want the semantics of a ConcurrentMap without the strong keys, you can't get that out-of-the-box, but Guava provides a pretty good alternative .) (如果您想要没有强键的ConcurrentMap的语义,则不能立即使用,但Guava提供了一个很好的选择 。)

You may also want to check that the keys that you're .put() ing into the map have properly implemented .equals() and .hashCode() . 您可能还需要检查将.put()放入映射中的键是否已正确实现.equals().hashCode()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM