diff --git a/java-oom/src/main/java/com/kwai/koom/javaoom/common/KConfig.java b/java-oom/src/main/java/com/kwai/koom/javaoom/common/KConfig.java index 72eff68e..303815ed 100644 --- a/java-oom/src/main/java/com/kwai/koom/javaoom/common/KConfig.java +++ b/java-oom/src/main/java/com/kwai/koom/javaoom/common/KConfig.java @@ -1,10 +1,10 @@ package com.kwai.koom.javaoom.common; -import static com.kwai.koom.javaoom.common.KGlobalConfig.KOOM_DIR; +import com.kwai.koom.javaoom.monitor.HeapThreshold; import java.io.File; -import com.kwai.koom.javaoom.monitor.HeapThreshold; +import static com.kwai.koom.javaoom.common.KGlobalConfig.KOOM_DIR; /** * Copyright 2020 Kwai, Inc. All rights reserved. @@ -59,6 +59,7 @@ public static KConfig defaultConfig() { public static class KConfigBuilder { private float heapRatio; + private float heapMaxRatio; private int heapOverTimes; private int heapPollInterval; @@ -68,6 +69,7 @@ public static class KConfigBuilder { public KConfigBuilder() { this.heapRatio = KConstants.HeapThreshold.getDefaultPercentRation(); + this.heapMaxRatio = KConstants.HeapThreshold.getDefaultMaxPercentRation(); this.heapOverTimes = KConstants.HeapThreshold.OVER_TIMES; this.heapPollInterval = KConstants.HeapThreshold.POLL_INTERVAL; File cacheFile = KGlobalConfig.getApplication().getCacheDir(); @@ -85,6 +87,11 @@ public KConfigBuilder heapRatio(float heapRatio) { return this; } + public KConfigBuilder heapMaxRatio(float heapMaxRatio) { + this.heapMaxRatio = heapMaxRatio; + return this; + } + public KConfigBuilder heapOverTimes(int heapOverTimes) { this.heapOverTimes = heapOverTimes; return this; @@ -101,8 +108,11 @@ public KConfigBuilder processName(String name) { } public KConfig build() { + if (heapRatio > heapMaxRatio) { + throw new RuntimeException("heapMaxRatio be greater than heapRatio"); + } HeapThreshold heapThreshold = new HeapThreshold(heapRatio, - heapOverTimes, heapPollInterval); + heapMaxRatio, heapOverTimes, heapPollInterval); return new KConfig(heapThreshold, this.rootDir, this.processName); } } diff --git a/java-oom/src/main/java/com/kwai/koom/javaoom/common/KConstants.java b/java-oom/src/main/java/com/kwai/koom/javaoom/common/KConstants.java index eaa33aa1..b642c217 100644 --- a/java-oom/src/main/java/com/kwai/koom/javaoom/common/KConstants.java +++ b/java-oom/src/main/java/com/kwai/koom/javaoom/common/KConstants.java @@ -2,8 +2,6 @@ import static com.kwai.koom.javaoom.common.KConstants.Bytes.MB; -import android.util.Log; - /** * Copyright 2020 Kwai, Inc. All rights reserved. *

@@ -38,6 +36,8 @@ public static class HeapThreshold { public static float PERCENT_RATIO_IN_256_DEVICE = 85; public static float PERCENT_RATIO_IN_128_DEVICE = 90; + public static float PERCENT_MAX_RATIO = 95; + public static float getDefaultPercentRation() { int maxMem = (int) (Runtime.getRuntime().maxMemory() / MB); if (Debug.VERBOSE_LOG) { @@ -53,6 +53,10 @@ public static float getDefaultPercentRation() { return KConstants.HeapThreshold.PERCENT_RATIO_IN_512_DEVICE; } + public static float getDefaultMaxPercentRation() { + return KConstants.HeapThreshold.PERCENT_MAX_RATIO; + } + public static int OVER_TIMES = 3; public static int POLL_INTERVAL = 5000; } diff --git a/java-oom/src/main/java/com/kwai/koom/javaoom/monitor/FdThreshold.java b/java-oom/src/main/java/com/kwai/koom/javaoom/monitor/FdThreshold.java index d35a1a0a..e2227c9a 100644 --- a/java-oom/src/main/java/com/kwai/koom/javaoom/monitor/FdThreshold.java +++ b/java-oom/src/main/java/com/kwai/koom/javaoom/monitor/FdThreshold.java @@ -28,6 +28,11 @@ public float value() { return DEFAULT_FD_COUNT; } + @Override + public float maxValue() { + return 0; + } + @Override public int overTimes() { return DEFAULT_OVER_TIMES; diff --git a/java-oom/src/main/java/com/kwai/koom/javaoom/monitor/HeapMonitor.java b/java-oom/src/main/java/com/kwai/koom/javaoom/monitor/HeapMonitor.java index aca58d93..a9af0010 100644 --- a/java-oom/src/main/java/com/kwai/koom/javaoom/monitor/HeapMonitor.java +++ b/java-oom/src/main/java/com/kwai/koom/javaoom/monitor/HeapMonitor.java @@ -1,7 +1,5 @@ package com.kwai.koom.javaoom.monitor; -import android.util.Log; - import com.kwai.koom.javaoom.common.KConstants; import com.kwai.koom.javaoom.common.KGlobalConfig; import com.kwai.koom.javaoom.common.KLog; @@ -57,12 +55,19 @@ public boolean isTrigger() { HeapStatus heapStatus = currentHeapStatus(); + if (heapStatus.isOverMaxThreshold) { + // 已达到最大阀值,强制触发trigger,防止后续出现大内存分配导致OOM进程Crash,无法触发trigger + KLog.i(TAG, "heap used is over max ratio, force trigger and over times reset to 0"); + currentTimes = 0; + return true; + } + if (heapStatus.isOverThreshold) { KLog.i(TAG, "heap status used:" + heapStatus.used / KConstants.Bytes.MB - + ", max:" + heapStatus.max / KConstants.Bytes.MB - + ", last over times:" + currentTimes); + + ", max:" + heapStatus.max / KConstants.Bytes.MB + + ", last over times:" + currentTimes); if (heapThreshold.ascending()) { - if (lastHeapStatus == null || heapStatus.used >= lastHeapStatus.used) { + if (lastHeapStatus == null || heapStatus.used >= lastHeapStatus.used || heapStatus.isOverMaxThreshold) { currentTimes++; } else { KLog.i(TAG, "heap status used is not ascending, and over times reset to 0"); @@ -86,7 +91,9 @@ private HeapStatus currentHeapStatus() { heapStatus.max = Runtime.getRuntime().maxMemory(); heapStatus.used = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); KLog.i(TAG, 100.0f * heapStatus.used / heapStatus.max + " " + heapThreshold.value()); - heapStatus.isOverThreshold = 100.0f * heapStatus.used / heapStatus.max > heapThreshold.value(); + float heapInPercent = 100.0f * heapStatus.used / heapStatus.max; + heapStatus.isOverThreshold = heapInPercent > heapThreshold.value(); + heapStatus.isOverMaxThreshold = heapInPercent > heapThreshold.maxValue(); return heapStatus; } @@ -94,6 +101,7 @@ static class HeapStatus { long max; long used; boolean isOverThreshold; + boolean isOverMaxThreshold; } @Override diff --git a/java-oom/src/main/java/com/kwai/koom/javaoom/monitor/HeapThrashingThreshold.java b/java-oom/src/main/java/com/kwai/koom/javaoom/monitor/HeapThrashingThreshold.java index 97856617..c85fde56 100644 --- a/java-oom/src/main/java/com/kwai/koom/javaoom/monitor/HeapThrashingThreshold.java +++ b/java-oom/src/main/java/com/kwai/koom/javaoom/monitor/HeapThrashingThreshold.java @@ -30,6 +30,11 @@ public float value() { return DEFAULT_THRASH_SIZE * KConstants.Bytes.MB; } + @Override + public float maxValue() { + return 0; + } + @Override public int overTimes() { return DEFAULT_OVER_TIMES; diff --git a/java-oom/src/main/java/com/kwai/koom/javaoom/monitor/HeapThreshold.java b/java-oom/src/main/java/com/kwai/koom/javaoom/monitor/HeapThreshold.java index 2ecd9409..b4140d08 100644 --- a/java-oom/src/main/java/com/kwai/koom/javaoom/monitor/HeapThreshold.java +++ b/java-oom/src/main/java/com/kwai/koom/javaoom/monitor/HeapThreshold.java @@ -20,11 +20,13 @@ public class HeapThreshold implements Threshold { private float heapRatioInPercent; + private float heapMaxRatioInPercent; private int overTimes; private int pollInterval; - public HeapThreshold(float heapRatioInPercent, int overTimes, int pollInterval) { + public HeapThreshold(float heapRatioInPercent, float heapMaxRatioInPercent, int overTimes, int pollInterval) { this.heapRatioInPercent = heapRatioInPercent; + this.heapMaxRatioInPercent = heapMaxRatioInPercent; this.overTimes = overTimes; this.pollInterval = pollInterval; } @@ -34,6 +36,11 @@ public float value() { return heapRatioInPercent; } + @Override + public float maxValue() { + return heapMaxRatioInPercent; + } + @Override public int overTimes() { return overTimes; diff --git a/java-oom/src/main/java/com/kwai/koom/javaoom/monitor/ThreadThreshold.java b/java-oom/src/main/java/com/kwai/koom/javaoom/monitor/ThreadThreshold.java index 961f000a..bc575b71 100644 --- a/java-oom/src/main/java/com/kwai/koom/javaoom/monitor/ThreadThreshold.java +++ b/java-oom/src/main/java/com/kwai/koom/javaoom/monitor/ThreadThreshold.java @@ -28,6 +28,11 @@ public float value() { return DEFAULT_THREAD_COUNT; } + @Override + public float maxValue() { + return 0; + } + @Override public int overTimes() { return DEFAULT_OVER_TIMES; diff --git a/java-oom/src/main/java/com/kwai/koom/javaoom/monitor/Threshold.java b/java-oom/src/main/java/com/kwai/koom/javaoom/monitor/Threshold.java index 7d95351b..541cb6b5 100644 --- a/java-oom/src/main/java/com/kwai/koom/javaoom/monitor/Threshold.java +++ b/java-oom/src/main/java/com/kwai/koom/javaoom/monitor/Threshold.java @@ -20,10 +20,15 @@ public interface Threshold { /** - * @return value + * @return value 触发trigger的最低阀值,且必须命中策略heapOverTimes次才会真正触发 */ float value(); + /** + * @return maxValue 达到这个最大阀值,强制触发trigger + */ + float maxValue(); + /** * @return threshold crossed times */