我编写了一个Java程序,它构建了一个巨大的arraylist(超过700万个元素)。然后迭代那个arraylist的元素,我正在建立第二个arraylist,其大小也像是数百万。在迭代期间的某个时刻,超出GC开销限制时出现内存异常。
我想到了一个解决方案,就像每当第二个arraylist的大小达到1万时,我会将其元素保存到文件或数据库表中并在该arraylist上调用removeall()。 但是这个调用会强制垃圾收集元素吗?如果没有,那么我的问题仍然没有解决。
提前感谢任何有用的建议。
答案 0 :(得分:1)
调用 您需要做的是减少可到达对象的数量和大小。这意味着当垃圾收集运行时,它将回收更多垃圾,您的应用程序将能够继续。 听起来你限制第二个数组大小的策略可以通过减少可达对象的工作集来提供帮助。另一种可能性是使用 或者,只需增加JVM的最大堆大小。removeAll
不会触发垃圾回收,手动触发垃圾回收也无济于事。让垃圾收集按需要发生。 (您可以确保在应用程序获得OOME之前将 运行。只有在运行完整GC 后没有足够的空间时才会抛出OOME。)< / p>
ArrayList.set(pos, null)
来清空第一个列表中不再需要的条目。不幸的是,您的问题中没有足够的细节可以提供更多帮助。
答案 1 :(得分:0)
仅当删除了对列表中对象的所有引用时。
答案 2 :(得分:0)
垃圾收集器将根据需要自动运行。您可以通过System.gc()
手动调用它,但这对您的情况没有帮助。
有a post解释错误的含义,具体说明如何禁用错误:
如果在垃圾收集中花费了太多时间,则并行/并发收集器将抛出OutOfMemoryError:如果在垃圾收集中花费了超过98%的总时间并且恢复了少于2%的堆,则OutOfMemoryError将被抛出。此功能旨在防止应用程序长时间运行,同时由于堆太小而很少或没有进度。如有必要,可以通过在命令行中添加选项 -XX:-UseGCOverheadLimit 来禁用此功能。