我想解析一个文件并将其作为Map<aID, Set<bID>>
保存在内存中。
unique_a_IDs = 50.000;
unique_b_IDs = 1.000;
avg_set_length = 50;
如您所见,摘要中的所有设置都会保留unique_a_IDs * avg_set_length = 2.500.000
bIDs
。每个bID
的范围是0到1000. 因此,平均每个bID
将存储2500次。而且我不希望JVM为每个整数分配2500次内存。
是否有任何技巧可以保持数据结构的内存效率?
问题在于我无法(至少我不知道如何)使用java的整数/字符串池。整数池仅适用于-128 ... 127范围内的数字。字符串池仅适用于编译时常量,但我从文件中读取bID
。
import java.util.*;
public class MemoryTest {
private final static Integer A_IDS_AMOUNT = 65536;
private final static Integer B_IDS_AMOUNT = 1000;
private final static Integer AVERAGE_SET_LENGTH = 50;
private final static Random rand = new Random();
public static void main(String [] args) {
Map<Integer, Set<Integer>> map = new HashMap<>(A_IDS_AMOUNT);
for (int i = 0; i < A_IDS_AMOUNT; i++) {
Set<Integer> set = genRandomSet();
map.put(i, set);
}
// Where SizeOf is premain class which use java instruments
long size = new SizeOf().deepsize(map) / (1024 * 1024);
System.out.println("Bytes used by object: " + size + " Mb"); //results in 175 Mb
}
private static Set<Integer> genRandomSet() {
Set<Integer> set = new HashSet<>(AVERAGE_SET_LENGTH);
for (int i = 0; i < AVERAGE_SET_LENGTH; i++) {
set.add(rand.nextInt(B_IDS_AMOUNT));
}
return set;
}
}
答案 0 :(得分:2)
Java 7及更高版本中的java.lang.Integer.IntegerCache.high
系统属性可以设置(例如-Djava.lang.Integer.IntegerCache.high=<size>
)以将整数缓存到高于默认值 - 请参阅{的源代码{1}}。
但是我怀疑这对你有多大帮助,因为你java.lang.Integer.IntegerCache
和Map
消耗的内存要多得多。
答案 1 :(得分:1)
创建要与地图元素关联的集合时,可以检查以前是否已构建相同的集合。如果您可以将此集合与地图元素相关联。这样,重复的集合只存储一次。构建时间可能很昂贵,但最后,你有一个更紧凑的结构(例如map.get(idx1)是map.get(idx2)的相同集合/对象)。如果相反的设置是 - 所有 - 不同,我认为你没有任何机会优化它。