gpt4 book ai didi

Java:填充内存中排序的批处理

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:56:13 26 4
gpt4 key购买 nike

所以我使用 Java 对以行分隔的元组的大型磁盘文件进行多路外部合并。成批的元组被读入 TreeSet,然后被转储到磁盘上排序的批处理中。一旦所有的数据都用完了,这些批处理就会被合并排序到输出中。

目前我正在使用魔数(Magic Number)来计算我们可以放入内存中的元组数量。这是基于一个静态图,该图表明每 MB 堆空间可以粗略地容纳多少元组,以及有多少堆空间可用:

long max = Runtime.getRuntime().maxMemory();
long used = Runtime.getRuntime().totalMemory();
long free = Runtime.getRuntime().freeMemory();
long space = free + (max - used);

然而,这并不总是那么有效,因为我们可能正在对不同长度的元组进行排序(对此,每 MB 的静态元组数字可能过于保守),而我现在想使用享元模式在其中加入更多内容,这可能会使数字更加多变。

所以我正在寻找一种更好的方法来将堆空间填满。理想情况下,解决方案应该是:

  • 可靠(没有堆空间异常的风险)
  • 灵活(不基于静态数字)
  • 高效(例如,不在每个元组之后轮询运行时内存估计)

有什么想法吗?

最佳答案

由于垃圾收集器的垃圾处理,将堆填满可能不是一个好主意。 (当内存接近满时,垃圾收集的效率接近于 0,因为收集的努力取决于堆大小,但释放的内存量取决于识别为无法访问的对象的大小)。

但是,如果你必须这样做,难道你不能简单地按照下面的方式来做吗?

for (;;) {
long freeSpace = getFreeSpace();
if (freeSpace < 1000000) break;
for (;;freeSpace > 0) {
treeSet.add(readRecord());
freeSpace -= MAX_RECORD_SIZE;
}
}

发现空闲内存的调用很少见,因此不会对性能造成太大影响。例如,如果您有 1 GB 的堆空间,并留出 1MB 的空间,并且 MAX_RECORD_SIZE 是平均记录大小的十倍,则 getFreeSpace() 将被调用仅仅是一个 log(1000 )/-log(0.9) ~= 66 次。

关于Java:填充内存中排序的批处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6484944/

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