From 63e687ca94a3bc6a38db3c6e3e18ee66e77c3b56 Mon Sep 17 00:00:00 2001 From: MingzhenHan Date: Tue, 27 Aug 2024 19:25:47 +0800 Subject: [PATCH 1/6] Add jvm memory monitor feature --- .../hugegraph/config/ServerOptions.java | 18 +++ .../backend/store/BackendEntryIterator.java | 2 +- .../static/conf/rest-server.properties | 6 +- .../hugegraph/dist/HugeGraphServer.java | 7 ++ .../apache/hugegraph/dist/MemoryMonitor.java | 119 ++++++++++++++++++ 5 files changed, 149 insertions(+), 3 deletions(-) create mode 100644 hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/MemoryMonitor.java diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/config/ServerOptions.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/config/ServerOptions.java index 084e9a338f..159327034c 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/config/ServerOptions.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/config/ServerOptions.java @@ -21,6 +21,7 @@ import static org.apache.hugegraph.config.OptionChecker.disallowEmpty; import static org.apache.hugegraph.config.OptionChecker.nonNegativeInt; import static org.apache.hugegraph.config.OptionChecker.positiveInt; +import static org.apache.hugegraph.config.OptionChecker.rangeDouble; import static org.apache.hugegraph.config.OptionChecker.rangeInt; public class ServerOptions extends OptionHolder { @@ -321,4 +322,21 @@ public static synchronized ServerOptions instance() { nonNegativeInt(), 1000L ); + + public static final ConfigOption JVM_MEMORY_MONITOR_THRESHOLD = + new ConfigOption<>( + "memory_monitor.threshold", + "Threshold for JVM memory usage monitoring, 1 means disabling the memory " + + "monitoring thread.", + rangeDouble(0.0, 1.0), + 0.85 + ); + + public static final ConfigOption JVM_MEMORY_MONITOR_PERIOD = + new ConfigOption<>( + "memory_monitor.period", + "The period of JVM memory usage monitoring, the unit is milliseconds.", + nonNegativeInt(), + 2000 + ); } diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendEntryIterator.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendEntryIterator.java index f13798dd63..20469f77aa 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendEntryIterator.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/backend/store/BackendEntryIterator.java @@ -94,7 +94,7 @@ public Object metadata(String meta, Object... args) { public static final void checkInterrupted() { if (Thread.interrupted()) { - throw new BackendException("Interrupted, maybe it is timed out", + throw new BackendException("Interrupted, maybe it is timed out or uses too much memory", new InterruptedException()); } } diff --git a/hugegraph-server/hugegraph-dist/src/assembly/static/conf/rest-server.properties b/hugegraph-server/hugegraph-dist/src/assembly/static/conf/rest-server.properties index f89966e6cd..4d79eed35e 100644 --- a/hugegraph-server/hugegraph-dist/src/assembly/static/conf/rest-server.properties +++ b/hugegraph-server/hugegraph-dist/src/assembly/static/conf/rest-server.properties @@ -1,7 +1,5 @@ # bind url -# could use '0.0.0.0' or specified (real)IP to expose external network access restserver.url=http://127.0.0.1:8080 -#restserver.enable_graphspaces_filter=false # gremlin server url, need to be consistent with host and port in gremlin-server.yaml #gremlinserver.url=http://127.0.0.1:8182 @@ -53,3 +51,7 @@ server.role=master # slow query log log.slow_query_threshold=1000 + +# jvm memory usage monitor +memory_monitor.threshold=0.8 +memory_monitor.period=1000 diff --git a/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/HugeGraphServer.java b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/HugeGraphServer.java index ae2c73e2c5..da45726116 100644 --- a/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/HugeGraphServer.java +++ b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/HugeGraphServer.java @@ -37,6 +37,7 @@ public class HugeGraphServer { private final RestServer restServer; private final GremlinServer gremlinServer; + private final MemoryMonitor memoryMonitor; public static void register() { RegisterUtil.registerBackends(); @@ -78,9 +79,15 @@ public HugeGraphServer(String gremlinServerConf, String restServerConf) } finally { System.setSecurityManager(securityManager); } + + // Start Memory Monitor Task + this.memoryMonitor = new MemoryMonitor(restServerConf); + this.memoryMonitor.start(); } public void stop() { + this.memoryMonitor.stop(); + try { this.gremlinServer.stop().get(); LOG.info("HugeGremlinServer stopped"); diff --git a/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/MemoryMonitor.java b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/MemoryMonitor.java new file mode 100644 index 0000000000..711df30e0d --- /dev/null +++ b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/MemoryMonitor.java @@ -0,0 +1,119 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.dist; + +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryUsage; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import org.apache.hugegraph.config.HugeConfig; +import org.apache.hugegraph.config.ServerOptions; +import org.apache.hugegraph.util.Log; +import org.slf4j.Logger; + +import com.sun.management.ThreadMXBean; + +public class MemoryMonitor { + + private static final Logger LOG = Log.logger(MemoryMonitor.class); + private final double MEMORY_MONITOR_THRESHOLD; + private final int MEMORY_MONITOR_PERIOD; + private final ScheduledExecutorService scheduler; + + public MemoryMonitor(String restServerConf) { + HugeConfig restServerConfig = new HugeConfig(restServerConf); + MEMORY_MONITOR_THRESHOLD = + restServerConfig.get(ServerOptions.JVM_MEMORY_MONITOR_THRESHOLD); + MEMORY_MONITOR_PERIOD = + restServerConfig.get(ServerOptions.JVM_MEMORY_MONITOR_PERIOD); + scheduler = Executors.newScheduledThreadPool(1); + } + + private void manageMemory() { + double memoryUsagePercentage = getMemoryUsagePercentage(); + + if (memoryUsagePercentage > MEMORY_MONITOR_THRESHOLD) { + LOG.info("JVM memory usage is '{}', exceeding the threshold of '{}'.", + memoryUsagePercentage, MEMORY_MONITOR_THRESHOLD); + System.gc(); + LOG.info("Trigger System.gc()"); + + double doubleCheckUsage = getMemoryUsagePercentage(); + if (doubleCheckUsage > MEMORY_MONITOR_THRESHOLD) { + Thread targetThread = getHighestMemoryThread(); + if (targetThread != null) { + LOG.info("JVM memory usage is '{}', exceeding the threshold of '{}'.", + doubleCheckUsage, MEMORY_MONITOR_THRESHOLD); + targetThread.interrupt(); + LOG.info("Send interrupt to '{}' thread", + targetThread.getName()); + } + } + } + } + + private double getMemoryUsagePercentage() { + MemoryUsage heapMemoryUsage = + ManagementFactory.getMemoryMXBean().getHeapMemoryUsage(); + return (double) heapMemoryUsage.getUsed() / heapMemoryUsage.getMax(); + } + + private Thread getHighestMemoryThread() { + long highestMemory = 0; + Thread highestThread = null; + + ThreadMXBean threadMXBean = (ThreadMXBean) ManagementFactory.getThreadMXBean(); + + for (Thread thread : Thread.getAllStackTraces().keySet()) { + if (thread.getState() != Thread.State.RUNNABLE || + thread.getName() == null || + !thread.getName().startsWith("grizzly-http-server-")) { + continue; + } + + long threadMemory = + threadMXBean.getThreadAllocatedBytes(thread.getId()); + if (threadMemory > highestMemory) { + highestMemory = threadMemory; + highestThread = thread; + } + } + + return highestThread; + } + + public void start() { + if (MEMORY_MONITOR_THRESHOLD >= 1.0) { + return; + } + Runnable task = this::manageMemory; + scheduler.scheduleAtFixedRate(task, 0, MEMORY_MONITOR_PERIOD, + TimeUnit.MILLISECONDS); + LOG.info("Memory monitoring task started."); + } + + public void stop() { + if (MEMORY_MONITOR_THRESHOLD >= 1.0) { + return; + } + scheduler.shutdownNow(); + LOG.info("Memory monitoring task ended."); + } +} From c1439c9a0774b8ad73c4c712024b3c7a898f04b6 Mon Sep 17 00:00:00 2001 From: MingzhenHan <124570399+MingzhenHan@users.noreply.github.com> Date: Tue, 27 Aug 2024 19:34:09 +0800 Subject: [PATCH 2/6] Update jvm memory monitor parameters --- .../src/assembly/static/conf/rest-server.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hugegraph-server/hugegraph-dist/src/assembly/static/conf/rest-server.properties b/hugegraph-server/hugegraph-dist/src/assembly/static/conf/rest-server.properties index 4d79eed35e..71ab6f5231 100644 --- a/hugegraph-server/hugegraph-dist/src/assembly/static/conf/rest-server.properties +++ b/hugegraph-server/hugegraph-dist/src/assembly/static/conf/rest-server.properties @@ -53,5 +53,5 @@ server.role=master log.slow_query_threshold=1000 # jvm memory usage monitor -memory_monitor.threshold=0.8 -memory_monitor.period=1000 +memory_monitor.threshold=0.85 +memory_monitor.period=2000 From 30219d7248355484d26915e5b6c2b6a6ccac7d32 Mon Sep 17 00:00:00 2001 From: MingzhenHan <124570399+MingzhenHan@users.noreply.github.com> Date: Wed, 28 Aug 2024 14:10:11 +0800 Subject: [PATCH 3/6] Update rest-server.properties --- .../src/assembly/static/conf/rest-server.properties | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hugegraph-server/hugegraph-dist/src/assembly/static/conf/rest-server.properties b/hugegraph-server/hugegraph-dist/src/assembly/static/conf/rest-server.properties index 71ab6f5231..0c568823c4 100644 --- a/hugegraph-server/hugegraph-dist/src/assembly/static/conf/rest-server.properties +++ b/hugegraph-server/hugegraph-dist/src/assembly/static/conf/rest-server.properties @@ -1,5 +1,7 @@ # bind url +# could use '0.0.0.0' or specified (real)IP to expose external network access restserver.url=http://127.0.0.1:8080 +#restserver.enable_graphspaces_filter=false # gremlin server url, need to be consistent with host and port in gremlin-server.yaml #gremlinserver.url=http://127.0.0.1:8182 From 9f67893dc40ae0f8a9b0c5f0530c36dcb5351398 Mon Sep 17 00:00:00 2001 From: MingzhenHan Date: Fri, 4 Oct 2024 22:15:14 +0800 Subject: [PATCH 4/6] code review advice modify --- .../hugegraph/config/ServerOptions.java | 7 +-- .../apache/hugegraph/dist/MemoryMonitor.java | 49 ++++++++++--------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/config/ServerOptions.java b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/config/ServerOptions.java index 159327034c..5c5aa86e3d 100644 --- a/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/config/ServerOptions.java +++ b/hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/config/ServerOptions.java @@ -327,15 +327,16 @@ public static synchronized ServerOptions instance() { new ConfigOption<>( "memory_monitor.threshold", "Threshold for JVM memory usage monitoring, 1 means disabling the memory " + - "monitoring thread.", + "monitoring task.", rangeDouble(0.0, 1.0), 0.85 ); - public static final ConfigOption JVM_MEMORY_MONITOR_PERIOD = + public static final ConfigOption JVM_MEMORY_MONITOR_DETECT_PERIOD = new ConfigOption<>( "memory_monitor.period", - "The period of JVM memory usage monitoring, the unit is milliseconds.", + "The period in ms of JVM memory usage monitoring, in each period we will " + + "detect the jvm memory usage and take corresponding actions.", nonNegativeInt(), 2000 ); diff --git a/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/MemoryMonitor.java b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/MemoryMonitor.java index 711df30e0d..9cb506f03b 100644 --- a/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/MemoryMonitor.java +++ b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/MemoryMonitor.java @@ -19,12 +19,12 @@ import java.lang.management.ManagementFactory; import java.lang.management.MemoryUsage; -import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import org.apache.hugegraph.config.HugeConfig; import org.apache.hugegraph.config.ServerOptions; +import org.apache.hugegraph.util.ExecutorUtil; import org.apache.hugegraph.util.Log; import org.slf4j.Logger; @@ -34,19 +34,19 @@ public class MemoryMonitor { private static final Logger LOG = Log.logger(MemoryMonitor.class); private final double MEMORY_MONITOR_THRESHOLD; - private final int MEMORY_MONITOR_PERIOD; + private final int MEMORY_MONITOR_DETECT_PERIOD; private final ScheduledExecutorService scheduler; public MemoryMonitor(String restServerConf) { HugeConfig restServerConfig = new HugeConfig(restServerConf); MEMORY_MONITOR_THRESHOLD = restServerConfig.get(ServerOptions.JVM_MEMORY_MONITOR_THRESHOLD); - MEMORY_MONITOR_PERIOD = - restServerConfig.get(ServerOptions.JVM_MEMORY_MONITOR_PERIOD); - scheduler = Executors.newScheduledThreadPool(1); + MEMORY_MONITOR_DETECT_PERIOD = + restServerConfig.get(ServerOptions.JVM_MEMORY_MONITOR_DETECT_PERIOD); + this.scheduler = ExecutorUtil.newScheduledThreadPool("memory-monitor-thread-%d"); } - private void manageMemory() { + private void runMemoryDetect() { double memoryUsagePercentage = getMemoryUsagePercentage(); if (memoryUsagePercentage > MEMORY_MONITOR_THRESHOLD) { @@ -57,14 +57,9 @@ private void manageMemory() { double doubleCheckUsage = getMemoryUsagePercentage(); if (doubleCheckUsage > MEMORY_MONITOR_THRESHOLD) { - Thread targetThread = getHighestMemoryThread(); - if (targetThread != null) { - LOG.info("JVM memory usage is '{}', exceeding the threshold of '{}'.", - doubleCheckUsage, MEMORY_MONITOR_THRESHOLD); - targetThread.interrupt(); - LOG.info("Send interrupt to '{}' thread", - targetThread.getName()); - } + LOG.info("JVM memory usage is '{}', exceeding the threshold of '{}'.", + doubleCheckUsage, MEMORY_MONITOR_THRESHOLD); + interruptHighestMemoryThread(); } } } @@ -81,7 +76,9 @@ private Thread getHighestMemoryThread() { ThreadMXBean threadMXBean = (ThreadMXBean) ManagementFactory.getThreadMXBean(); - for (Thread thread : Thread.getAllStackTraces().keySet()) { + Thread[] threads = new Thread[Thread.activeCount()]; + Thread.enumerate(threads); + for (Thread thread : threads) { if (thread.getState() != Thread.State.RUNNABLE || thread.getName() == null || !thread.getName().startsWith("grizzly-http-server-")) { @@ -95,25 +92,33 @@ private Thread getHighestMemoryThread() { highestThread = thread; } } - return highestThread; } + private void interruptHighestMemoryThread() { + Thread targetThread = getHighestMemoryThread(); + if (targetThread != null) { + targetThread.interrupt(); + LOG.info("Send interrupt to '{}' thread", + targetThread.getName()); + } + } + public void start() { if (MEMORY_MONITOR_THRESHOLD >= 1.0) { + LOG.info("Invalid parameter, MEMORY_MONITOR_THRESHOLD should less than 1.0."); return; } - Runnable task = this::manageMemory; - scheduler.scheduleAtFixedRate(task, 0, MEMORY_MONITOR_PERIOD, - TimeUnit.MILLISECONDS); - LOG.info("Memory monitoring task started."); + this.scheduler.scheduleAtFixedRate(this::runMemoryDetect, 0, MEMORY_MONITOR_DETECT_PERIOD, + TimeUnit.MILLISECONDS); + LOG.info("Memory monitoring started."); } public void stop() { if (MEMORY_MONITOR_THRESHOLD >= 1.0) { return; } - scheduler.shutdownNow(); - LOG.info("Memory monitoring task ended."); + this.scheduler.shutdownNow(); + LOG.info("Memory monitoring stoped."); } } From 310c8d7e1a81acc64f4ecbdaab75b7b86821b440 Mon Sep 17 00:00:00 2001 From: MingzhenHan <124570399+MingzhenHan@users.noreply.github.com> Date: Wed, 9 Oct 2024 22:12:18 +0800 Subject: [PATCH 5/6] modify LOG type --- .../java/org/apache/hugegraph/dist/MemoryMonitor.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/MemoryMonitor.java b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/MemoryMonitor.java index 9cb506f03b..876f00ad58 100644 --- a/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/MemoryMonitor.java +++ b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/MemoryMonitor.java @@ -50,14 +50,14 @@ private void runMemoryDetect() { double memoryUsagePercentage = getMemoryUsagePercentage(); if (memoryUsagePercentage > MEMORY_MONITOR_THRESHOLD) { - LOG.info("JVM memory usage is '{}', exceeding the threshold of '{}'.", + LOG.warn("JVM memory usage is '{}', exceeding the threshold of '{}'.", memoryUsagePercentage, MEMORY_MONITOR_THRESHOLD); System.gc(); - LOG.info("Trigger System.gc()"); + LOG.warn("Trigger System.gc()"); double doubleCheckUsage = getMemoryUsagePercentage(); if (doubleCheckUsage > MEMORY_MONITOR_THRESHOLD) { - LOG.info("JVM memory usage is '{}', exceeding the threshold of '{}'.", + LOG.warn("JVM memory usage is '{}', exceeding the threshold of '{}'.", doubleCheckUsage, MEMORY_MONITOR_THRESHOLD); interruptHighestMemoryThread(); } @@ -99,7 +99,7 @@ private void interruptHighestMemoryThread() { Thread targetThread = getHighestMemoryThread(); if (targetThread != null) { targetThread.interrupt(); - LOG.info("Send interrupt to '{}' thread", + LOG.warn("Send interrupt to '{}' thread", targetThread.getName()); } } From 219f48f982567da9b321d652b6299291b5e818be Mon Sep 17 00:00:00 2001 From: MingzhenHan Date: Tue, 15 Oct 2024 17:46:26 +0800 Subject: [PATCH 6/6] improve code --- .../static/conf/rest-server.properties | 2 +- .../hugegraph/dist/HugeGraphServer.java | 2 +- .../apache/hugegraph/dist/MemoryMonitor.java | 22 ++++++++----------- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/hugegraph-server/hugegraph-dist/src/assembly/static/conf/rest-server.properties b/hugegraph-server/hugegraph-dist/src/assembly/static/conf/rest-server.properties index 0c568823c4..9d6bb2ca82 100644 --- a/hugegraph-server/hugegraph-dist/src/assembly/static/conf/rest-server.properties +++ b/hugegraph-server/hugegraph-dist/src/assembly/static/conf/rest-server.properties @@ -54,6 +54,6 @@ server.role=master # slow query log log.slow_query_threshold=1000 -# jvm memory usage monitor +# jvm(in-heap) memory usage monitor, set 1 to disable it memory_monitor.threshold=0.85 memory_monitor.period=2000 diff --git a/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/HugeGraphServer.java b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/HugeGraphServer.java index da45726116..2652324f44 100644 --- a/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/HugeGraphServer.java +++ b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/HugeGraphServer.java @@ -80,7 +80,7 @@ public HugeGraphServer(String gremlinServerConf, String restServerConf) System.setSecurityManager(securityManager); } - // Start Memory Monitor Task + // Start (In-Heap) Memory Monitor this.memoryMonitor = new MemoryMonitor(restServerConf); this.memoryMonitor.start(); } diff --git a/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/MemoryMonitor.java b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/MemoryMonitor.java index 876f00ad58..18b7cc170f 100644 --- a/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/MemoryMonitor.java +++ b/hugegraph-server/hugegraph-dist/src/main/java/org/apache/hugegraph/dist/MemoryMonitor.java @@ -47,7 +47,7 @@ public MemoryMonitor(String restServerConf) { } private void runMemoryDetect() { - double memoryUsagePercentage = getMemoryUsagePercentage(); + double memoryUsagePercentage = getMemoryUsageRatio(); if (memoryUsagePercentage > MEMORY_MONITOR_THRESHOLD) { LOG.warn("JVM memory usage is '{}', exceeding the threshold of '{}'.", @@ -55,7 +55,7 @@ private void runMemoryDetect() { System.gc(); LOG.warn("Trigger System.gc()"); - double doubleCheckUsage = getMemoryUsagePercentage(); + double doubleCheckUsage = getMemoryUsageRatio(); if (doubleCheckUsage > MEMORY_MONITOR_THRESHOLD) { LOG.warn("JVM memory usage is '{}', exceeding the threshold of '{}'.", doubleCheckUsage, MEMORY_MONITOR_THRESHOLD); @@ -64,9 +64,8 @@ private void runMemoryDetect() { } } - private double getMemoryUsagePercentage() { - MemoryUsage heapMemoryUsage = - ManagementFactory.getMemoryMXBean().getHeapMemoryUsage(); + private double getMemoryUsageRatio() { + MemoryUsage heapMemoryUsage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage(); return (double) heapMemoryUsage.getUsed() / heapMemoryUsage.getMax(); } @@ -79,14 +78,12 @@ private Thread getHighestMemoryThread() { Thread[] threads = new Thread[Thread.activeCount()]; Thread.enumerate(threads); for (Thread thread : threads) { - if (thread.getState() != Thread.State.RUNNABLE || - thread.getName() == null || + if (thread.getState() != Thread.State.RUNNABLE || thread.getName() == null || !thread.getName().startsWith("grizzly-http-server-")) { continue; } - long threadMemory = - threadMXBean.getThreadAllocatedBytes(thread.getId()); + long threadMemory = threadMXBean.getThreadAllocatedBytes(thread.getId()); if (threadMemory > highestMemory) { highestMemory = threadMemory; highestThread = thread; @@ -99,14 +96,13 @@ private void interruptHighestMemoryThread() { Thread targetThread = getHighestMemoryThread(); if (targetThread != null) { targetThread.interrupt(); - LOG.warn("Send interrupt to '{}' thread", - targetThread.getName()); + LOG.warn("Send interrupt to '{}' thread", targetThread.getName()); } } public void start() { if (MEMORY_MONITOR_THRESHOLD >= 1.0) { - LOG.info("Invalid parameter, MEMORY_MONITOR_THRESHOLD should less than 1.0."); + LOG.info("Invalid parameter, MEMORY_MONITOR_THRESHOLD should ≤ 1.0."); return; } this.scheduler.scheduleAtFixedRate(this::runMemoryDetect, 0, MEMORY_MONITOR_DETECT_PERIOD, @@ -119,6 +115,6 @@ public void stop() { return; } this.scheduler.shutdownNow(); - LOG.info("Memory monitoring stoped."); + LOG.info("Memory monitoring stopped."); } }