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 <[email protected]>
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);
}
}