【问题标题】:Getting the OutOfMemoryError when generating a Cartesian product of large lists生成大型列表的笛卡尔积时出现 OutOfMemoryError
【发布时间】:2016-08-05 20:02:16
【问题描述】:

我正在尝试使用此代码在 Java 中生成 List 的笛卡尔积:

private static List<List<String>> getCartesian(List<List<String>> initialList) {
    List<List<String>> result = new ArrayList<List<String>>();
    result.add(new ArrayList<String>());
    for (List<String> first : initialList) {
        List<List<String>> temporaryList = new ArrayList<List<String>>();
        for (List<String> second : result) {
            for (String word : first) {
                List<String> tmp2 = new ArrayList<String>(second);
                tmp2.add(word);
                temporaryList.add(tmp2);
            }
        }
        result = temporaryList;
    }
    return result;
}

我在使用大型列表时收到以下错误:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

我该怎么做才能让它在大数据上发挥作用?

【问题讨论】:

  • 查看 JVM 选项 -Xmx。
  • 您是否需要同时在内存中保存所有这些列表?制作完成后,您打算如何处理产品?
  • 使用命令行选项 -Xmx 运行 Java,该选项设置堆的最大大小。我认为默认值为 512M,因此请注意:您为此功能使用了大量内存...
  • 我尝试增加 JVM 堆大小,但没有结果。对于每个这些笛卡尔我做这个:java.util.List&lt;java.util.List&lt;String&gt;&gt; allCombinations=cartesianProduct(subsequence1); int [] scoreList=new int[allCombinations.size()]; for(int i=0;i&lt;allCombinations.size();i++) scoreList[i]= getScore(allCombinations.get(i));我怎样才能修改这个方法来只得到这个scoreList。

标签: java list out-of-memory cartesian-product


【解决方案1】:

您应该尽量避免将ArrayList 用于此类事情。生成结果所需的所有信息都包含在原始List&lt;List&lt;String&gt;&gt; 中,因此无需同时将所有答案都保存在内存中。

以下代码生成一个等于getCartesian 的列表,但它不会将其全部存储在一个大ArrayList 中。相反,它会复制所有原始列表并在请求时计算单个答案。

public static List<List<String>> getCartesian2(List<List<String>> lists) {
    long size = 1;
    final List<List<String>> copy = new ArrayList<List<String>>();
    for (List<String> list : lists) {
        size *= list.size();
        if (size > Integer.MAX_VALUE)
            throw new IllegalArgumentException();
        copy.add(new ArrayList<String>(list));
    }
    final int fSize = (int) size;
    return new AbstractList<List<String>>() {
        @Override
        public int size() {
            return fSize;
        }
        @Override
        public List<String> get(int i) {
            if (i < 0 || i >= fSize)
                throw new IndexOutOfBoundsException();
            String[] arr = new String[copy.size()];
            for (int j = copy.size() - 1; j >= 0; j--)  {
                List<String> list = copy.get(j);
                arr[j] = list.get(i % list.size());
                i /= list.size();
            }
            return Arrays.asList(arr);
        }
    };
}

【讨论】:

    猜你喜欢
    • 2016-10-08
    • 2022-11-17
    • 1970-01-01
    • 2021-05-06
    • 1970-01-01
    • 2021-09-05
    • 2012-03-24
    • 2016-05-07
    • 2012-11-18
    相关资源
    最近更新 更多