繁体   English   中英

如何处理 Java 中的 hashmap 导致的 memory 泄漏

[英]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.

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