[英]How to deal with memory leak due to hashmap in Java
我正在开发一个插件。 我在哪里得到 java.lang.OutOfMemoryError: Java 堆空间。 我尝试增加堆的大小,它适用于较少的数据,但适用于大数据时它会失败。 我尝试使用 MAT 分析 memory 泄漏,似乎 hashmap 导致了这个问题。
我在几乎所有的课程中都使用 hashmap 如下所示从文件中获取一些属性。 这里 hasmap 包含一些常量,如项目根和一些键值对常量。
Key Value
Project_root D:/..
CAT_Product Product Category
我可以为 hashmap 使用什么替代方案,或者我应该清理 hashmap 中的数据。 我很不确定什么是理想的解决方案。
private final HashMap<String, String> properties = new HashMap<String, String>();
public void execute() {
this.mistlogger = MistLogger.getInstance();
MIST.ROOT = this.properties.get(Constants.ROJECT_ROOT_DIR);
this.updateData = ProjectAnalyzer.getCatalogDetails(MIST.ROOT, Constants.Unit);
this.files = this.properties.get(Constants.FILES);
}
在再次遇到 OutOfMemoryError 之前,可以尝试以下一些选项,它们可能有助于延长应用程序的生命周期。
首先,总是有-Xms
和-Xmx
memory 选项来扩展 VM 使用的 memory。
如果您的应用程序从数据库或文件加载大量字符串,而不是声明String x = "value"
(已经是intern
版本),您可以尝试调用String.intern()
来获取字符串的内部形式。 仅当同一组 String 键和值经常在不同的 HashMap 或应用程序中的任何值中重复时,这才会有所帮助。
map.put(key.intern(), value.intern());
HashMap 在达到其负载因子大小时会自动扩展其内部缓冲区,因此您经常会在map.put()
将旧表复制到新表时看到 OOM。 您可以强制tablesize
的构造函数修复大表大小和 1.0f 负载因子。 我认为如果map.size()
远小于 tablesize 并且如果map.size()
比 tablesize 大得多,它会减慢每次检索的速度,但会浪费存储空间。
private final HashMap<String, String> properties = new HashMap<String, String>(tablesize, 1.0f);
但是,您应该仔细考虑什么是必不可少的 memory 存储空间与您可以按需转储 + 重新加载的数据,并且还可以考虑使用SoftReference
来处理非必要的项目,一个时间戳来识别旧数据, map.remove
on不必要的数据,因此可以帮助 GC 清理,但代价是您必须稍后重新加载。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.