如果 java.lang.OutOfMemoryError 即将发生,请执行此操作

Do if java.lang.OutOfMemoryError is about to happen

我正在测试一个游戏解算器,它跟踪 Map<Long, Integer> solvedPositions 中已解决的位置,其中 LongpositionID 并且 Integer 拥有最小的已知层数以达到该位置。求解器处理较小的电路板,但在较大的电路板上导致 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 大小是否超过特定值作为 trim 的触发器,但是是否有本地方法来检查 JVM 是否接近内存限制?

您可以查看 MemoryMXBean 以查看是否可以为您提供所需的内容,因为它表示:

Java 虚拟机内存系统的管理接口。

您可以进一步阅读 here

I can check if Map size exceeds certain value as a trigger for trim, but is there a native way to check if JVM is close to memory limit?

您可以使用 Java 代理来检测您的程序。
这是官方文档:https://docs.oracle.com/javase/7/docs/api/java/lang/instrument/package-summary.html and a question 关于 SO 中的内容。

如果您使用的是 OpenJDK,则可以使用 jol 工具: http://openjdk.java.net/projects/code-tools/jol/

这个想法是您确定您的地图应该达到哪个八位字节大小以触发地图上的 trim 操作。
然后在您的应用程序中,当您的地图达到一定数量的元素时,您可以计算地图的八位字节大小以检查是否达到阈值以及是否应该 trim 它。