存储有效的方法来存储大量重复的整数> 127

时间:2016-10-25 10:39:33

标签: java string integer

我想解析一个文件并将其作为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;
    }
}

2 个答案:

答案 0 :(得分:2)

Java 7及更高版本中的java.lang.Integer.IntegerCache.high系统属性可以设置(例如-Djava.lang.Integer.IntegerCache.high=<size>)以将整数缓存到高于默认值 - 请参阅{的源代码{1}}。

但是我怀疑这对你有多大帮助,因为你java.lang.Integer.IntegerCacheMap消耗的内存要多得多。

答案 1 :(得分:1)

创建要与地图元素关联的集合时,可以检查以前是否已构建相同的集合。如果您可以将此集合与地图元素相关联。这样,重复的集合只存储一次。构建时间可能很昂贵,但最后,你有一个更紧凑的结构(例如map.get(idx1)是map.get(idx2)的相同集合/对象)。如果相反的设置是 - 所有 - 不同,我认为你没有任何机会优化它。