Java:clear()大尺寸列表有助于快速垃圾收集吗?

标签 java list memory-management garbage-collection

从数据库 1 加载 150 万条记录

从数据库 2 加载 150 万条记录

List<DannDB> dDb = fromNamedQuery(); //return em.createNamedQuery("").getResultList();
List<LannDB> lDb = fromNamedQuery();

比较其数据。

更新/持久化到数据库(使用 JPA)

节目在两小时后结束。

同样的迭代每三个小时发生一次,很多时候会出现内存不足的情况。

以下语句是否有效,对象是否超出范围?

 dDb.clear();

  or 

 dDb = null

或者我还能做什么?

最佳答案

假设您的目标是减少 OOME 的发生,而不是考虑所有其他因素......

分配nullList object 将使整个列表符合垃圾回收的条件。然后,您需要创建一个新的(可能是空的)列表来替换它。

调用clear()将具有与清零和重新创建类似的效果1,但详细信息取决于 List执行。 (例如,在 clear() 上调用 ArrayList 不会释放后备数组。它只是将数组单元格清空。)

如果你可以回收ArrayList对于与原始大小大致相同的列表,您可以在增长列表时避免垃圾。 (但我们不知道这是 ArrayList!)

您的用例中的另一个因素是:

List<DannDB> dDb = fromNamedQuery();

(大概)无论如何都会创建一个新列表。这将呈现 clear()无意义。 (只需将 null 分配给 dDb ,或者让变量超出范围或重新分配新列表。)

最后一个问题是,可以想象该列表是可以最终确定的。这可能意味着删除列表对象需要更长的时间。

总的来说,我不能说分配 null 中的哪一个并调用clear()对于内存占用会更好。或者其中任何一个都会产生重大影响。但您没有理由不能尝试两种选择,并观察会发生什么。

我可以建议的唯一其他事情是:

  • 增加堆大小(以及 RAM 占用空间)。
  • 更改应用程序,以便您无需将整个数据库快照保存在内存中。根据比较的性质,您可以按“ block ”进行比较或通过流式传输记录2

最后一个是唯一可扩展的解决方案;也就是说,这将适用于越来越多的记录。 (对处理更多记录所需的时间取模。)


重要说明:

  1. 手动运行 System.gc() 不太有帮助。充其量它只会让你的应用程序变慢。
  2. 由于真正的问题是出现 OOME,因此任何试图通过将内存返还给操作系统来让 JVM 缩小堆的行为都会适得其反。

1 - 从存储管理的角度来看类似。显然,清除列表和创建新列表之间存在语义差异;例如如果您的应用程序的其他部分引用了原始列表。
2 - 你们中足够大的人会记得使用磁带存储实现工资单系统的经典方法。如果您可以按相同的键顺序从两个数据源中进行选择,您也许可以使用经典方法来比较它们。例如,并行读取两个结果集。

关于Java:clear()大尺寸列表有助于快速垃圾收集吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67901163/

相关文章:

java - 修改模块名称后Eclipse IDE不运行Java应用程序

java socket对象内存泄漏

list - Flutter 将 Map 转换为 JSON 列表

c - 为什么我没有得到堆栈溢出?

android - 是否有必要将图像存储在内存中以在android中的 ListView 上显示

java - 如何验证没有调用模拟对象的方法?莫基托

java - DataFormatter (org.apache.poi) 删除了我的零

Python:被要求输入两次并输出重复的打印语句

python - 从列表中删除标点符号

node.js - 如何在node.js中使用大量内存?