gpt4 book ai didi

java - 将集合转换为数组,无需额外内存

转载 作者:行者123 更新时间:2023-11-30 08:07:57 24 4
gpt4 key购买 nike

我需要将 Map 转换为 2D 数组,所以我写了这段代码,但它占用了大量内存,我不明白为什么。

private DataItem[][] convertDataToArrays(boolean[] filter,
Map<Integer, List<T>> dataSet)
double[] data = new double[sizeOfNewVector];
DataItem[][] reducedData = new DataItem[dataSet.size()][];
for (int i = dataSet.size() - 1; i >= 0; i--) {
reducedData[i] = new DataItem[dataSet.get(i).size()];
for (int j = reducedData[i].length - 1; j >= 0; j--) {
reducedData[i][(reducedData[i].length - 1) - j] = new DataItem(data);
dataSet.get(i).remove(j);
}
dataSet.remove(i);
}
return reducedData;

这是 DataItem 类:

public class DataItem {

public double[] data;

public DataItem(double[] data) {
this.data = new double[data.length];
System.arraycopy(data, 0, this.data, 0, data.length);
}
}

算法应该做什么:

  1. 从列表中取出最后一个元素
  2. 复制它。
  3. 从列表中删除元素
  4. 将副本存储到新的二维数组中
  5. 重复直到列表为空

这应该适用于 map 中的所有列表。

问题是,第 3 步只保留元素并且不缩小数组,因此当我在转换方法中插入一个巨大的数据集时,我遇到了 java.lang.OutOfMemoryError: GC 开销限制超出

我需要在没有任何额外内存的情况下完成它。请问有人可以帮我吗?

编辑:

我正在使用 ArrayList 和 HashMap。

最佳答案

你的理论是完全可能的。 ArrayList 确实需要一段时间来缩小用于存储引用的内部数组的大小。您可以通过使用另一个 List 实现(例如 LinkedList)来避免这种影响,该实现不会显示此行为,但它们也会产生相当大的内存开销,可能会耗尽您节省的空间。

话虽这么说,考虑到您的数据结构,我发现仅 ArrayList 中的一些额外引用的开销不太可能将您的内存需求推高。我发现更有可能的是,您正在创建所有显然相对较大(从内部数组来看)的 DataItem 类型对象的副本。如果其他人仍然拥有对原始 DataItem 对象的引用,则您对 remove 的调用将从列表中删除他们的引用,但对象本身保持 Activity 状态,直到所有对它们的引用被删除。

我建议检查您的内存占用量,使用一个实际有效的较小示例,使用类似 MAT tool 的内容。 。查看转换前和转换后有多少个 DataItem 类型的对象。如果它们增加,我的理论是正确的,您应该通过不复制对象,而只是复制它们的引用(如果可以的话),或者通过摆脱来避免这个问题对旧对象的附加引用。如果我的理论是错误的,请检查内存的哪一部分增加最多以找出罪魁祸首。

关于java - 将集合转换为数组,无需额外内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30830683/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com