【发布时间】:2012-08-12 00:18:31
【问题描述】:
我为自定义表编写了一个自定义索引,该表使用 500MB 的堆来存储 500k 个字符串。只有 10% 的字符串是唯一的;其余的都是重复的。每个字符串的长度为 4。
如何优化我的代码?我应该使用另一个集合吗?我尝试实现一个自定义字符串池来节省内存:
public class StringPool {
private static WeakHashMap<String, String> map = new WeakHashMap<>();
public static String getString(String str) {
if (map.containsKey(str)) {
return map.get(str);
} else {
map.put(str, str);
return map.get(str);
}
}
}
private void buildIndex() {
if (monitorModel.getMessageIndex() == null) {
// the index, every columns create an index
ArrayList<HashMap<String, TreeSet<Integer>>> messageIndex = new ArrayList<>(filterableColumn.length);
for (int i = filterableColumn.length; i >= 0; i--) {
// key -> string, value -> treeset, the row wich contains the key
HashMap<String, TreeSet<Integer>> hash = new HashMap<>();
messageIndex.add(hash);
}
// create index for every column
for (int i = monitorModel.getParser().getMyMessages().getMessages().size() - 1; i >= 0; --i) {
TreeSet<Integer> tempList;
for (int j = 0; j < filterableColumn.length; j++) {
String value = StringPool.getString(getValueAt(i, j).toString());
if (!messageIndex.get(j).containsKey(value)) {
tempList = new TreeSet<>();
messageIndex.get(j).put(value, tempList);
} else {
tempList = messageIndex.get(j).get(value);
}
tempList.add(i);
}
}
monitorModel.setMessageIndex(messageIndex);
}
}
【问题讨论】:
-
500,000 4 个字符串只有几十兆的内存,根本没有缓存。认为你找错地方了。
-
我同意 Affe 的观点,即不应超过几 MB,即使假设每 4 个字母字符串 50 字节(这是悲观的)也只会让您达到 25MB。
-
ArrayList
>> -- 哇,这是一个结构! :) 使用这种数据结构会产生巨大的开销。这很可能是高内存消耗的原因,而不是字符串本身。我前段时间写过一篇关于 Java Collection 开销的博文:plumbr.eu/blog/fat-collections -
谢谢,我搜索这种答案,我会看你的博客。
标签: java memory-leaks out-of-memory heap-memory