You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2022/06/20 02:31:08 UTC
[dubbo] branch 3.0 updated: Improve: enhance scheduled executor for MemoryLimitCalculator (#10178)
This is an automated email from the ASF dual-hosted git repository.
liujun pushed a commit to branch 3.0
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/3.0 by this push:
new 23f517a904 Improve: enhance scheduled executor for MemoryLimitCalculator (#10178)
23f517a904 is described below
commit 23f517a904fcf1554b78f22dfa13dd53ab7a3a19
Author: Albumen Kevin <jh...@gmail.com>
AuthorDate: Mon Jun 20 10:31:02 2022 +0800
Improve: enhance scheduled executor for MemoryLimitCalculator (#10178)
---
.../common/threadpool/MemoryLimitCalculator.java | 35 ++++++++++++++++------
1 file changed, 26 insertions(+), 9 deletions(-)
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/threadpool/MemoryLimitCalculator.java b/dubbo-common/src/main/java/org/apache/dubbo/common/threadpool/MemoryLimitCalculator.java
index 31db9e0508..1be3d6c5a1 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/threadpool/MemoryLimitCalculator.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/threadpool/MemoryLimitCalculator.java
@@ -17,9 +17,13 @@
package org.apache.dubbo.common.threadpool;
+import org.apache.dubbo.common.resource.GlobalResourcesRepository;
+import org.apache.dubbo.common.utils.NamedThreadFactory;
+
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
/**
* {@link java.lang.Runtime#freeMemory()} technology is used to calculate the
@@ -33,26 +37,37 @@ public class MemoryLimitCalculator {
private static volatile long maxAvailable;
- private static final ScheduledExecutorService SCHEDULER = Executors.newSingleThreadScheduledExecutor();
-
- static {
- // immediately refresh when this class is loaded to prevent maxAvailable from being 0
- refresh();
- // check every 50 ms to improve performance
- SCHEDULER.scheduleWithFixedDelay(MemoryLimitCalculator::refresh, 50, 50, TimeUnit.MILLISECONDS);
- Runtime.getRuntime().addShutdownHook(new Thread(SCHEDULER::shutdown));
- }
+ private static final AtomicBoolean refreshStarted = new AtomicBoolean(false);
private static void refresh() {
maxAvailable = Runtime.getRuntime().freeMemory();
}
+ private static void checkAndScheduleRefresh() {
+ if (!refreshStarted.get()) {
+ // immediately refresh when first call to prevent maxAvailable from being 0
+ // to ensure that being refreshed before refreshStarted being set as true
+ // notice: refresh may be called for more than once because there is no lock
+ refresh();
+ if (refreshStarted.compareAndSet(false, true)) {
+ ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("Dubbo-Memory-Calculator"));
+ // check every 50 ms to improve performance
+ scheduledExecutorService.scheduleWithFixedDelay(MemoryLimitCalculator::refresh, 50, 50, TimeUnit.MILLISECONDS);
+ GlobalResourcesRepository.registerGlobalDisposable(() -> {
+ refreshStarted.set(false);
+ scheduledExecutorService.shutdown();
+ });
+ }
+ }
+ }
+
/**
* Get the maximum available memory of the current JVM.
*
* @return maximum available memory
*/
public static long maxAvailable() {
+ checkAndScheduleRefresh();
return maxAvailable;
}
@@ -67,6 +82,7 @@ public class MemoryLimitCalculator {
if (percentage <= 0 || percentage > 1) {
throw new IllegalArgumentException();
}
+ checkAndScheduleRefresh();
return (long) (maxAvailable() * percentage);
}
@@ -76,6 +92,7 @@ public class MemoryLimitCalculator {
* @return available memory
*/
public static long defaultLimit() {
+ checkAndScheduleRefresh();
return (long) (maxAvailable() * 0.8);
}
}