从数据库1加载150万条记录
从 db2 加载150万条记录
List<DannDB> dDb = fromNamedQuery(); //return em.createNamedQuery("").getResultList();
List<LannDB> lDb = fromNamedQuery();
比较其数据。
更新/保存到数据库(使用JPA)
两小时后节目结束。
同样的迭代每三个小时发生一次,并且多次给予内存不足。
下面的语句是否有效,对象是否超出了此范围?
dDb.clear();
or
dDb = null
或者我还能做什么
4条答案
按热度按时间cedebl8k1#
假设您的目标是减少OOME的发生,而不是考虑所有其他因素...
将
null
分配给List
对象将使整个列表符合垃圾收集的条件。然后,您需要创建一个新的(可能是空的)列表来替换它。调用
clear()
将有一个 * 类似 * 的效果1空和重新创建,但细节将取决于List
的实现。(例如,在ArrayList
上调用clear()
不会释放后台数组。它只会使数组单元格为空。)如果您可以回收一个
ArrayList
,得到一个与原始列表大小大致相同的列表,那么就可以在增长列表时避免垃圾。(但我们不知道这是一个ArrayList
!)您的用例中的另一个因素是:
无论如何都将创建一个新列表。这将使
clear()
变得毫无意义。(只需将null
分配给dDb
,或者让变量超出范围或重新分配给新列表。最后一个问题是,可以想象该清单是可以最后确定的。这可能意味着删除列表对象需要更长的时间。
总的来说,我不能说分配
null
和调用clear()
哪一个对内存占用更好。或者说,这两种情况中的任何一种都会产生重大影响。但是没有理由你不能尝试两种选择,并观察会发生什么。我唯一能建议的是:
最后一个是唯一可扩展的解决方案;即,其将对更大数量的记录起作用。(对处理更多记录所需的时间取模。)
重要提示:
1.手动运行
System.gc()
* 不太可能 * 有帮助。最好的情况下,它会(只是)使你的应用程序变慢。1.由于真实的的问题是您得到了OOME,因此任何试图让JVM通过将内存返回给操作系统来缩小堆的做法都将适得其反。
1 -从存储管理的Angular 看类似。显然,清除列表和创建新列表之间存在语义差异;例如,如果您的应用程序的某些其他部分引用了原始列表。
2 -那些年龄足够大的人会记得用磁带存储实现工资单系统的经典方法。如果您可以从两个数据源中以相同的键顺序进行选择,则可以使用经典方法来比较它们。例如,并行阅读两个结果集。
ddarikpa2#
对于SQL,可以获取两个
[ResultSet](https://docs.oracle.com/javase/8/docs/api/java/sql/ResultSet.html)
并迭代地比较它们的数据。这样,您就不必首先保存所有数据。出于演示目的,我假设您的数据如下所示:
| 字符串电子邮件1|字符串电子邮件2| int someInt|
| --------------|--------------|--------------|
| abc@def.ghi | jkl@mno.pqr |1234567|
| xyz@gmail.com | | 8901234 |
要检测此数据库的两个
ResultSet
之间的差异,请执行以下操作:要将
ResultSet oldData
的内容(及其对应的数据库连接)设置为ResultSet newData
:当然,如果你不在乎这两个集合的行数不同,你可以省略
if(a.isLast()!=newData.isLast)) ...
和if(oldData.isLast()!=newData.isLast()) ...
。jhiyze9q3#
问题是,默认情况下,一旦分配了堆内存大小就不会缩小(我指的是从操作系统分配的内存大小)。如果您的Java应用程序曾经需要2GB的RAM,默认情况下,它将保留操作系统的RAM。
如果可以的话,请尝试更改应用程序的设计,不要首先将所有数据加载到内存中,而只加载工作真正需要的数据。
如果您确实需要同时执行两个大批处理,请考虑使用以下Java命令行参数:“-XX:+UseAdaptiveSizePolicy”,这将使在大量内存使用后缩小堆空间成为可能。
您还可以通过“System.gc();“,但是a)在没有建议的命令行参数的情况下不会收缩分配的堆内存,b)真的,您不应该考虑这个问题。Java会自己运行它。
编辑:改进了我的第一个解释一点。
ymdaylpp4#
对于内存使用来说,最好的方法是列表不超出作用域。因此,最好(内存方面)逐个修改内容,只保留一个临时条目对象,而不是整个其他列表。
因此,您可以创建
getNextFromNamedQuery()
和hasNextInNamedQuery()
方法,并将数据设置为当前索引。例如: