如果 java.lang.OutOfMemoryError 即将发生,请执行
Posted
技术标签:
【中文标题】如果 java.lang.OutOfMemoryError 即将发生,请执行【英文标题】:Do if java.lang.OutOfMemoryError is about to happen 【发布时间】:2017-05-03 07:50:51 【问题描述】:我正在测试一个游戏求解器,它在Map<Long, Integer> solvedPositions
中跟踪已解决的位置,其中Long
是positionID
和Integer
持有最小的已知层数以达到该位置。 Solver 处理较小的电路板,但在较大的电路板上导致 java.lang.OutOfMemoryError: GC overhead limit exceeded
。增加内存大小是不切实际的,因为足够大的电路板将拥有比给定计算机上的内存容量更多的位置。
我想这样做:
...
boolean isTimeToTrimRecords = willResizedMapExceedMemLimit();
if(isTimeToTrimRecords)
int maxDepthOfRecordedPlies = getMaxDepth();
removeLastPly(solvedPositions, maxDepthOfRecordedPlies);
setMaxDepthOfRecordedPlies(maxDepthOfRecordedPlies-1);
...
public void removeLastPly(Map<Long, Integer> solvedPositions, int maxDepthOfRecordedPlies)
for (Map.Entry<Long, Integer> position : solvedPositions.entrySet())
Long positionID = position.getKey();
Integer value = position.getValue();
if(value==maxDepthOfRecordedPlies)
solvedPositions.remove(positionID);
我可以检查 Map 大小是否超过某个值作为修剪的触发器,但是有没有本地方法来检查 JVM 是否接近内存限制?
【问题讨论】:
你做了很多内存分析;因此,您确定您的代码中没有导致泄漏的错误(或者可能在短时间内产生大量垃圾)。换句话说:您确定您的应用程序真的需要所有内存吗? 我会仔细检查/分析您的应用程序,或者对于一些估计值,使用运行时:***.com/questions/2015463/… 【参考方案1】:我可以检查地图大小是否超过某个值作为修剪的触发器, 但是有没有一种本地方法来检查 JVM 是否接近内存限制?
您可以使用 Java 代理来检测您的程序。 这是官方文档:https://docs.oracle.com/javase/7/docs/api/java/lang/instrument/package-summary.html 和question 关于 SO。
如果你在 OpenJDK 下,你可以使用 jol 工具: http://openjdk.java.net/projects/code-tools/jol/
您的想法是您确定地图应达到的八位字节大小以触发地图上的修剪操作。 然后在您的应用程序中,当您的地图达到一定数量的元素时,您可以计算地图的八位字节大小以检查是否达到阈值,因此是否应该修剪它。
【讨论】:
【参考方案2】:您可以查看MemoryMXBean,看看它是否可以为您提供您正在寻找的东西,因为它代表:
Java虚拟机内存系统的管理接口。
您可以在here 上找到一些进一步阅读。
【讨论】:
以上是关于如果 java.lang.OutOfMemoryError 即将发生,请执行的主要内容,如果未能解决你的问题,请参考以下文章