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);
     }
 }

Reply via email to