This is an automated email from the ASF dual-hosted git repository.

albumenj pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/dubbo-integration-cases.git


The following commit(s) were added to refs/heads/main by this push:
     new e96c1211 Enhance memory bench test case (#13)
e96c1211 is described below

commit e96c12117a15794156e7098157d5bb8d0480db46
Author: Albumen Kevin <[email protected]>
AuthorDate: Tue Mar 12 13:41:28 2024 +0800

    Enhance memory bench test case (#13)
---
 .../case-configuration.yml                         |   1 +
 99-integration/dubbo-samples-memory-server/pom.xml |   7 ++
 .../apache/dubbo/samples/provider/Application.java |   7 +-
 .../dubbo/samples/provider/QosServiceImpl.java     |  65 +++++++++++--
 .../src/main/resources/log4j2.xml                  |   2 +-
 .../dubbo/samples/client/GreetingServiceIT.java    | 101 ++++++++++++++-------
 .../case-configuration.yml                         |   1 +
 .../dubbo-samples-memory-tri-server/pom.xml        |   9 +-
 .../apache/dubbo/samples/provider/Application.java |   8 +-
 .../dubbo/samples/provider/QosServiceImpl.java     |  65 +++++++++++--
 .../dubbo/samples/client/GreetingServiceIT.java    | 101 ++++++++++++++-------
 99-integration/dubbo-samples-test-13560/pom.xml    |   2 +-
 test/dubbo-test-runner/src/docker/Dockerfile       |  12 ++-
 test/dubbo-test-runner/src/docker/run-dubbo-app.sh |   2 +-
 .../dubbo-test-runner/src/docker/run-dubbo-test.sh |   2 +-
 15 files changed, 289 insertions(+), 96 deletions(-)

diff --git a/99-integration/dubbo-samples-memory-server/case-configuration.yml 
b/99-integration/dubbo-samples-memory-server/case-configuration.yml
index f8d3a780..4b74a4d5 100644
--- a/99-integration/dubbo-samples-memory-server/case-configuration.yml
+++ b/99-integration/dubbo-samples-memory-server/case-configuration.yml
@@ -41,6 +41,7 @@ services:
       - "**/*IT.class"
     systemProps:
       - zookeeper.address=zookeeper
+      - provider_address=provider
     waitPortsBeforeRun:
       - zookeeper:2181
       - provider:20880
diff --git a/99-integration/dubbo-samples-memory-server/pom.xml 
b/99-integration/dubbo-samples-memory-server/pom.xml
index 91e7d9f8..60fccdcd 100644
--- a/99-integration/dubbo-samples-memory-server/pom.xml
+++ b/99-integration/dubbo-samples-memory-server/pom.xml
@@ -45,6 +45,7 @@
         <protobuf-java.version>3.24.3</protobuf-java.version>
         <junit5.version>5.9.2</junit5.version>
         <awaitility.version>4.2.0</awaitility.version>
+        <commons-io.version>2.15.1</commons-io.version>
     </properties>
 
     <dependencies>
@@ -114,5 +115,11 @@
             <artifactId>awaitility</artifactId>
             <version>${awaitility.version}</version>
         </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>${commons-io.version}</version>
+        </dependency>
+
     </dependencies>
 </project>
diff --git 
a/99-integration/dubbo-samples-memory-server/src/main/java/org/apache/dubbo/samples/provider/Application.java
 
b/99-integration/dubbo-samples-memory-server/src/main/java/org/apache/dubbo/samples/provider/Application.java
index aaf9d79d..2cd27179 100644
--- 
a/99-integration/dubbo-samples-memory-server/src/main/java/org/apache/dubbo/samples/provider/Application.java
+++ 
b/99-integration/dubbo-samples-memory-server/src/main/java/org/apache/dubbo/samples/provider/Application.java
@@ -26,9 +26,6 @@ import org.apache.dubbo.samples.api.GreetingsService;
 import org.apache.dubbo.samples.api.QosService;
 
 public class Application {
-    private static final String ZOOKEEPER_HOST = 
System.getProperty("zookeeper.address", "127.0.0.1");
-    private static final String ZOOKEEPER_PORT = 
System.getProperty("zookeeper.port", "2181");
-    private static final String ZOOKEEPER_ADDRESS = "zookeeper://" + 
ZOOKEEPER_HOST + ":" + ZOOKEEPER_PORT;
 
     public static void main(String[] args) {
         System.setProperty("dubbo.application.metadata.publish.delay", "1");
@@ -44,8 +41,8 @@ public class Application {
 
         DubboBootstrap dubboBootstrap = DubboBootstrap.getInstance()
                 .application(applicationConfig)
-                .registry(new RegistryConfig(ZOOKEEPER_ADDRESS))
-                .protocol(new ProtocolConfig("dubbo", -1))
+                .registry(new RegistryConfig("N/A"))
+                .protocol(new ProtocolConfig("dubbo", 20880))
                 .service(service)
                 .service(qosService)
                 .start();
diff --git 
a/99-integration/dubbo-samples-memory-server/src/main/java/org/apache/dubbo/samples/provider/QosServiceImpl.java
 
b/99-integration/dubbo-samples-memory-server/src/main/java/org/apache/dubbo/samples/provider/QosServiceImpl.java
index 6188a336..86550aa2 100644
--- 
a/99-integration/dubbo-samples-memory-server/src/main/java/org/apache/dubbo/samples/provider/QosServiceImpl.java
+++ 
b/99-integration/dubbo-samples-memory-server/src/main/java/org/apache/dubbo/samples/provider/QosServiceImpl.java
@@ -18,18 +18,31 @@ package org.apache.dubbo.samples.provider;
 
 import org.apache.dubbo.samples.api.QosService;
 
+import org.apache.commons.io.FileUtils;
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.lang.management.ManagementFactory;
 import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipInputStream;
 
 public class QosServiceImpl implements QosService {
     @Override
-    public long usedMemory() {
+    public synchronized long usedMemory() {
         String pid = 
ManagementFactory.getRuntimeMXBean().getName().split("@")[0];
+        new File("/tmp/analyze").mkdirs();
         try {
             Process process = Runtime.getRuntime().exec(
-                    String.format("jmap -histo:live %s", pid)
+                    String.format("jmap 
-dump:format=b,file=/tmp/analyze/dump.bin,live %s", pid)
             );
             StringBuilder stringBuilder = new StringBuilder();
             InputStreamReader streamReader = new 
InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8);
@@ -40,19 +53,55 @@ public class QosServiceImpl implements QosService {
                     stringBuilder.append(chars, 0, len);
                 }
             } while (process.isAlive());
+            System.out.println(stringBuilder);
 
-            String[] strings = stringBuilder.toString().split("\n");
-            for (String string : strings) {
-                if (string.contains("Total")) {
-                    String a = string.trim();
-                    String trim = a.substring(a.lastIndexOf(" ")).trim();
-                    return Long.parseLong(trim);
+            process = Runtime.getRuntime().exec(
+                    String.format("/usr/local/mat/ParseHeapDump.sh 
/tmp/analyze/dump.bin -format=csv -vm /usr/local/mat-jdk/bin 
org.eclipse.mat.api:overview", pid)
+            );
+            stringBuilder = new StringBuilder();
+            streamReader = new InputStreamReader(process.getInputStream(), 
StandardCharsets.UTF_8);
+            do {
+                char[] chars = new char[1024];
+                int len;
+                while ((len = streamReader.read(chars)) != -1) {
+                    stringBuilder.append(chars, 0, len);
+                }
+            } while (process.isAlive());
+            System.out.println(stringBuilder);
+
+            long size = -1;
+            ZipFile zf = new ZipFile("/tmp/analyze/dump_System_Overview.zip");
+            try (ZipInputStream zis = new 
ZipInputStream(Files.newInputStream(Paths.get("/tmp/analyze/dump_System_Overview.zip"))))
 {
+                ZipEntry entry = zis.getNextEntry();
+                while (entry != null) {
+                    String entryName = entry.getName();
+                    if (entryName.equals("pages/Heap_Dump_Overview2.csv")) {
+                        BufferedReader br = new BufferedReader(
+                                new 
InputStreamReader(zf.getInputStream(entry)));
+                        String line;
+                        while ((line = br.readLine()) != null) {
+                            System.out.println(line);
+                            if (line.startsWith("Number of objects")) {
+                                size = 
Long.parseLong(line.split("\"")[1].replaceAll(",", "").trim());
+                            }
+                        }
+                        br.close();
+                        break;
+                    }
+                    entry = zis.getNextEntry();
                 }
             }
+
+            FileUtils.deleteDirectory(new File("/tmp/analyze"));
+            if (size > -1) {
+                System.out.println("size: " + size);
+                return size;
+            }
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
 
         return Runtime.getRuntime().maxMemory() - 
Runtime.getRuntime().freeMemory();
     }
+
 }
diff --git 
a/99-integration/dubbo-samples-memory-server/src/main/resources/log4j2.xml 
b/99-integration/dubbo-samples-memory-server/src/main/resources/log4j2.xml
index 69e1321d..8cdef4ac 100644
--- a/99-integration/dubbo-samples-memory-server/src/main/resources/log4j2.xml
+++ b/99-integration/dubbo-samples-memory-server/src/main/resources/log4j2.xml
@@ -22,7 +22,7 @@
         </Console>
     </Appenders>
     <Loggers>
-        <Root level="info">
+        <Root level="error">
             <AppenderRef ref="Console"/>
         </Root>
     </Loggers>
diff --git 
a/99-integration/dubbo-samples-memory-server/src/test/java/org/apache/dubbo/samples/client/GreetingServiceIT.java
 
b/99-integration/dubbo-samples-memory-server/src/test/java/org/apache/dubbo/samples/client/GreetingServiceIT.java
index 6807591b..89c4041f 100644
--- 
a/99-integration/dubbo-samples-memory-server/src/test/java/org/apache/dubbo/samples/client/GreetingServiceIT.java
+++ 
b/99-integration/dubbo-samples-memory-server/src/test/java/org/apache/dubbo/samples/client/GreetingServiceIT.java
@@ -29,59 +29,96 @@ import org.apache.dubbo.samples.api.QosService;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
 class GreetingServiceIT {
     private static String zookeeperHost = 
System.getProperty("zookeeper.address", "127.0.0.1");
 
+    private final static long ACCEPTABLE_ERROR = 1000;
+
+    private final static ExecutorService EXECUTOR_SERVICE = 
Executors.newCachedThreadPool();
+
     @Test
     void test() {
         ReferenceConfig<QosService> qosReference = new ReferenceConfig<>();
         qosReference.setInterface(QosService.class);
+        qosReference.setUrl("dubbo://" + 
System.getProperty("provider_address", "127.0.0.1") + 
":20880?serialization=fastjson2&timeout=600000");
 
         DubboBootstrap.getInstance()
                 .application(new ApplicationConfig("first-dubbo-consumer"))
-                .registry(new RegistryConfig("zookeeper://" + zookeeperHost + 
":2181?enable-empty-protection=false"))
+                .registry(new RegistryConfig("N/A"))
                 .reference(qosReference)
                 .start();
 
-        bench(100);
-
         QosService qosService = qosReference.get();
-        long memoryStart = qosService.usedMemory();
+
+        for (int i = 0; i < 20; i++) {
+            bench(50);
+        }
+        for (int i = 0; i < 5; i++) {
+            bench(10);
+            qosService.usedMemory();
+        }
+
+        List<BigDecimal> memory = new ArrayList<>();
+        memory.add(BigDecimal.valueOf(qosService.usedMemory()));
 
         for (int i = 0; i < 10; i++) {
-            bench(100);
-            long endMemory = qosService.usedMemory();
-            System.out.println("Used: " + endMemory);
-            System.out.println("Delta: " + (endMemory - memoryStart));
-            Assertions.assertTrue((endMemory - memoryStart) < 100000);
+            bench(50);
+            memory.add(BigDecimal.valueOf(qosService.usedMemory()));
+            System.out.println(new Date() + " memory: " + memory.get(i) + " 
index: " + i);
         }
+
+        long avg = 
memory.stream().reduce(BigDecimal::add).get().divide(BigDecimal.valueOf(memory.size()),
 RoundingMode.DOWN).longValue();
+        for (int i = 0; i < memory.size(); i++) {
+            if (Math.abs(memory.get(i).longValue() - avg) > ACCEPTABLE_ERROR) {
+                Assertions.fail("memory leak, avg: " + avg + ", current: " + 
memory.get(i) + ", index: " + i);
+            }
+        }
+        System.out.println("avg: " + avg);
     }
 
     private static void bench(int range) {
-        IntStream.range(0, range)
-                .parallel()
-                .forEach((ignore)->{
-                    FrameworkModel frameworkModel = new FrameworkModel();
-                    ApplicationModel applicationModel = 
frameworkModel.newApplication();
-                    ReferenceConfig<GreetingsService> reference = new 
ReferenceConfig<>();
-                    reference.setInterface(GreetingsService.class);
-
-                    ApplicationConfig applicationConfig = new 
ApplicationConfig("first-dubbo-consumer");
-                    applicationConfig.setMetadataType("remote");
-                    applicationConfig.setQosEnable(false);
-                    DubboBootstrap.getInstance(applicationModel)
-                            .application(applicationConfig)
-                            .registry(new RegistryConfig("zookeeper://" + 
zookeeperHost + ":2181?enable-empty-protection=false"))
-                            .reference(reference)
-                            .start();
-
-                    GreetingsService service = reference.get();
-                    for (int i = 0; i < 10; i++) {
-                        service.sayHi("dubbo");
-                    }
-                    frameworkModel.destroy();
-                });
+        List<Future<?>> futures = new ArrayList<>();
+        for (int j = 0; j < range; j++) {
+            futures.add(EXECUTOR_SERVICE.submit(() -> {
+                FrameworkModel frameworkModel = new FrameworkModel();
+                ApplicationModel applicationModel = 
frameworkModel.newApplication();
+                ReferenceConfig<GreetingsService> reference = new 
ReferenceConfig<>();
+                reference.setInterface(GreetingsService.class);
+                reference.setUrl("dubbo://" + 
System.getProperty("provider_address", "127.0.0.1") + 
":20880?serialization=fastjson2");
+
+                ApplicationConfig applicationConfig = new 
ApplicationConfig("first-dubbo-consumer");
+                applicationConfig.setRegisterMode("interface");
+                DubboBootstrap.getInstance(applicationModel)
+                        .application(applicationConfig)
+                        .registry(new RegistryConfig("N/A"))
+                        .reference(reference)
+                        .start();
+
+                GreetingsService service = reference.get();
+                for (int i = 0; i < 1000; i++) {
+                    service.sayHi("dubbo");
+                }
+                frameworkModel.destroy();
+            }));
+        }
+        for (Future<?> future : futures) {
+            try {
+                future.get();
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
     }
+
 }
diff --git 
a/99-integration/dubbo-samples-memory-tri-server/case-configuration.yml 
b/99-integration/dubbo-samples-memory-tri-server/case-configuration.yml
index 72af9c33..72b73861 100644
--- a/99-integration/dubbo-samples-memory-tri-server/case-configuration.yml
+++ b/99-integration/dubbo-samples-memory-tri-server/case-configuration.yml
@@ -41,6 +41,7 @@ services:
       - "**/*IT.class"
     systemProps:
       - zookeeper.address=zookeeper
+      - provider_address=provider
     waitPortsBeforeRun:
       - zookeeper:2181
       - provider:50051
diff --git a/99-integration/dubbo-samples-memory-tri-server/pom.xml 
b/99-integration/dubbo-samples-memory-tri-server/pom.xml
index ac7e80d5..19c80aae 100644
--- a/99-integration/dubbo-samples-memory-tri-server/pom.xml
+++ b/99-integration/dubbo-samples-memory-tri-server/pom.xml
@@ -40,11 +40,12 @@
         <maven.compiler.target>1.8</maven.compiler.target>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 
-        <dubbo.version>3.2.6</dubbo.version>
+        <dubbo.version>3.2.11</dubbo.version>
         <protobuf-java.version>3.24.3</protobuf-java.version>
         <log4j2.version>2.20.0</log4j2.version>
         <junit5.version>5.9.2</junit5.version>
         <awaitility.version>4.2.0</awaitility.version>
+        <commons-io.version>2.15.1</commons-io.version>
     </properties>
 
     <dependencies>
@@ -97,6 +98,12 @@
             <version>${junit5.version}</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>${commons-io.version}</version>
+        </dependency>
+
         <dependency>
             <groupId>org.junit.jupiter</groupId>
             <artifactId>junit-jupiter-api</artifactId>
diff --git 
a/99-integration/dubbo-samples-memory-tri-server/src/main/java/org/apache/dubbo/samples/provider/Application.java
 
b/99-integration/dubbo-samples-memory-tri-server/src/main/java/org/apache/dubbo/samples/provider/Application.java
index 3c1cb735..bd30d706 100644
--- 
a/99-integration/dubbo-samples-memory-tri-server/src/main/java/org/apache/dubbo/samples/provider/Application.java
+++ 
b/99-integration/dubbo-samples-memory-tri-server/src/main/java/org/apache/dubbo/samples/provider/Application.java
@@ -26,9 +26,6 @@ import org.apache.dubbo.samples.api.GreetingsService;
 import org.apache.dubbo.samples.api.QosService;
 
 public class Application {
-    private static final String ZOOKEEPER_HOST = 
System.getProperty("zookeeper.address", "127.0.0.1");
-    private static final String ZOOKEEPER_PORT = 
System.getProperty("zookeeper.port", "2181");
-    private static final String ZOOKEEPER_ADDRESS = "zookeeper://" + 
ZOOKEEPER_HOST + ":" + ZOOKEEPER_PORT;
 
     public static void main(String[] args) {
         System.setProperty("dubbo.application.metadata.publish.delay", "1");
@@ -39,11 +36,12 @@ public class Application {
         qosService.setInterface(QosService.class);
         qosService.setRef(new QosServiceImpl());
         ApplicationConfig applicationConfig = new 
ApplicationConfig("first-dubbo-provider");
+        applicationConfig.setRegisterMode("interface");
 
         DubboBootstrap dubboBootstrap = DubboBootstrap.getInstance()
                 .application(applicationConfig)
-                .registry(new RegistryConfig(ZOOKEEPER_ADDRESS))
-                .protocol(new ProtocolConfig("tri", -1))
+                .registry(new RegistryConfig("N/A"))
+                .protocol(new ProtocolConfig("tri", 50051))
                 .service(service)
                 .service(qosService)
                 .start();
diff --git 
a/99-integration/dubbo-samples-memory-tri-server/src/main/java/org/apache/dubbo/samples/provider/QosServiceImpl.java
 
b/99-integration/dubbo-samples-memory-tri-server/src/main/java/org/apache/dubbo/samples/provider/QosServiceImpl.java
index 6188a336..86550aa2 100644
--- 
a/99-integration/dubbo-samples-memory-tri-server/src/main/java/org/apache/dubbo/samples/provider/QosServiceImpl.java
+++ 
b/99-integration/dubbo-samples-memory-tri-server/src/main/java/org/apache/dubbo/samples/provider/QosServiceImpl.java
@@ -18,18 +18,31 @@ package org.apache.dubbo.samples.provider;
 
 import org.apache.dubbo.samples.api.QosService;
 
+import org.apache.commons.io.FileUtils;
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.lang.management.ManagementFactory;
 import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipInputStream;
 
 public class QosServiceImpl implements QosService {
     @Override
-    public long usedMemory() {
+    public synchronized long usedMemory() {
         String pid = 
ManagementFactory.getRuntimeMXBean().getName().split("@")[0];
+        new File("/tmp/analyze").mkdirs();
         try {
             Process process = Runtime.getRuntime().exec(
-                    String.format("jmap -histo:live %s", pid)
+                    String.format("jmap 
-dump:format=b,file=/tmp/analyze/dump.bin,live %s", pid)
             );
             StringBuilder stringBuilder = new StringBuilder();
             InputStreamReader streamReader = new 
InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8);
@@ -40,19 +53,55 @@ public class QosServiceImpl implements QosService {
                     stringBuilder.append(chars, 0, len);
                 }
             } while (process.isAlive());
+            System.out.println(stringBuilder);
 
-            String[] strings = stringBuilder.toString().split("\n");
-            for (String string : strings) {
-                if (string.contains("Total")) {
-                    String a = string.trim();
-                    String trim = a.substring(a.lastIndexOf(" ")).trim();
-                    return Long.parseLong(trim);
+            process = Runtime.getRuntime().exec(
+                    String.format("/usr/local/mat/ParseHeapDump.sh 
/tmp/analyze/dump.bin -format=csv -vm /usr/local/mat-jdk/bin 
org.eclipse.mat.api:overview", pid)
+            );
+            stringBuilder = new StringBuilder();
+            streamReader = new InputStreamReader(process.getInputStream(), 
StandardCharsets.UTF_8);
+            do {
+                char[] chars = new char[1024];
+                int len;
+                while ((len = streamReader.read(chars)) != -1) {
+                    stringBuilder.append(chars, 0, len);
+                }
+            } while (process.isAlive());
+            System.out.println(stringBuilder);
+
+            long size = -1;
+            ZipFile zf = new ZipFile("/tmp/analyze/dump_System_Overview.zip");
+            try (ZipInputStream zis = new 
ZipInputStream(Files.newInputStream(Paths.get("/tmp/analyze/dump_System_Overview.zip"))))
 {
+                ZipEntry entry = zis.getNextEntry();
+                while (entry != null) {
+                    String entryName = entry.getName();
+                    if (entryName.equals("pages/Heap_Dump_Overview2.csv")) {
+                        BufferedReader br = new BufferedReader(
+                                new 
InputStreamReader(zf.getInputStream(entry)));
+                        String line;
+                        while ((line = br.readLine()) != null) {
+                            System.out.println(line);
+                            if (line.startsWith("Number of objects")) {
+                                size = 
Long.parseLong(line.split("\"")[1].replaceAll(",", "").trim());
+                            }
+                        }
+                        br.close();
+                        break;
+                    }
+                    entry = zis.getNextEntry();
                 }
             }
+
+            FileUtils.deleteDirectory(new File("/tmp/analyze"));
+            if (size > -1) {
+                System.out.println("size: " + size);
+                return size;
+            }
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
 
         return Runtime.getRuntime().maxMemory() - 
Runtime.getRuntime().freeMemory();
     }
+
 }
diff --git 
a/99-integration/dubbo-samples-memory-tri-server/src/test/java/org/apache/dubbo/samples/client/GreetingServiceIT.java
 
b/99-integration/dubbo-samples-memory-tri-server/src/test/java/org/apache/dubbo/samples/client/GreetingServiceIT.java
index 6807591b..30c1c0d9 100644
--- 
a/99-integration/dubbo-samples-memory-tri-server/src/test/java/org/apache/dubbo/samples/client/GreetingServiceIT.java
+++ 
b/99-integration/dubbo-samples-memory-tri-server/src/test/java/org/apache/dubbo/samples/client/GreetingServiceIT.java
@@ -29,59 +29,96 @@ import org.apache.dubbo.samples.api.QosService;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
 class GreetingServiceIT {
     private static String zookeeperHost = 
System.getProperty("zookeeper.address", "127.0.0.1");
 
+    private final static long ACCEPTABLE_ERROR = 200;
+
+    private final static ExecutorService EXECUTOR_SERVICE = 
Executors.newCachedThreadPool();
+
     @Test
     void test() {
         ReferenceConfig<QosService> qosReference = new ReferenceConfig<>();
         qosReference.setInterface(QosService.class);
+        qosReference.setUrl("tri://" + System.getProperty("provider_address", 
"127.0.0.1") + ":50051?serialization=fastjson2&timeout=600000");
 
         DubboBootstrap.getInstance()
                 .application(new ApplicationConfig("first-dubbo-consumer"))
-                .registry(new RegistryConfig("zookeeper://" + zookeeperHost + 
":2181?enable-empty-protection=false"))
+                .registry(new RegistryConfig("N/A"))
                 .reference(qosReference)
                 .start();
 
-        bench(100);
-
         QosService qosService = qosReference.get();
-        long memoryStart = qosService.usedMemory();
+
+        for (int i = 0; i < 20; i++) {
+            bench(50);
+        }
+        for (int i = 0; i < 5; i++) {
+            bench(10);
+            qosService.usedMemory();
+        }
+
+        List<BigDecimal> memory = new ArrayList<>();
+        memory.add(BigDecimal.valueOf(qosService.usedMemory()));
 
         for (int i = 0; i < 10; i++) {
-            bench(100);
-            long endMemory = qosService.usedMemory();
-            System.out.println("Used: " + endMemory);
-            System.out.println("Delta: " + (endMemory - memoryStart));
-            Assertions.assertTrue((endMemory - memoryStart) < 100000);
+            bench(50);
+            memory.add(BigDecimal.valueOf(qosService.usedMemory()));
+            System.out.println(new Date() + " memory: " + memory.get(i) + " 
index: " + i);
         }
+
+        long avg = 
memory.stream().reduce(BigDecimal::add).get().divide(BigDecimal.valueOf(memory.size()),
 RoundingMode.DOWN).longValue();
+        for (int i = 0; i < memory.size(); i++) {
+            if (Math.abs(memory.get(i).longValue() - avg) > ACCEPTABLE_ERROR) {
+                Assertions.fail("memory leak, avg: " + avg + ", current: " + 
memory.get(i) + ", index: " + i);
+            }
+        }
+        System.out.println("avg: " + avg);
     }
 
     private static void bench(int range) {
-        IntStream.range(0, range)
-                .parallel()
-                .forEach((ignore)->{
-                    FrameworkModel frameworkModel = new FrameworkModel();
-                    ApplicationModel applicationModel = 
frameworkModel.newApplication();
-                    ReferenceConfig<GreetingsService> reference = new 
ReferenceConfig<>();
-                    reference.setInterface(GreetingsService.class);
-
-                    ApplicationConfig applicationConfig = new 
ApplicationConfig("first-dubbo-consumer");
-                    applicationConfig.setMetadataType("remote");
-                    applicationConfig.setQosEnable(false);
-                    DubboBootstrap.getInstance(applicationModel)
-                            .application(applicationConfig)
-                            .registry(new RegistryConfig("zookeeper://" + 
zookeeperHost + ":2181?enable-empty-protection=false"))
-                            .reference(reference)
-                            .start();
-
-                    GreetingsService service = reference.get();
-                    for (int i = 0; i < 10; i++) {
-                        service.sayHi("dubbo");
-                    }
-                    frameworkModel.destroy();
-                });
+        List<Future<?>> futures = new ArrayList<>();
+        for (int j = 0; j < range; j++) {
+            futures.add(EXECUTOR_SERVICE.submit(() -> {
+                FrameworkModel frameworkModel = new FrameworkModel();
+                ApplicationModel applicationModel = 
frameworkModel.newApplication();
+                ReferenceConfig<GreetingsService> reference = new 
ReferenceConfig<>();
+                reference.setInterface(GreetingsService.class);
+                reference.setUrl("tri://" + 
System.getProperty("provider_address", "127.0.0.1") + 
":50051?serialization=fastjson2");
+
+                ApplicationConfig applicationConfig = new 
ApplicationConfig("first-dubbo-consumer");
+                applicationConfig.setRegisterMode("interface");
+                DubboBootstrap.getInstance(applicationModel)
+                        .application(applicationConfig)
+                        .registry(new RegistryConfig("N/A"))
+                        .reference(reference)
+                        .start();
+
+                GreetingsService service = reference.get();
+                for (int i = 0; i < 1000; i++) {
+                    service.sayHi("dubbo");
+                }
+                frameworkModel.destroy();
+            }));
+        }
+        for (Future<?> future : futures) {
+            try {
+                future.get();
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
     }
+
 }
diff --git a/99-integration/dubbo-samples-test-13560/pom.xml 
b/99-integration/dubbo-samples-test-13560/pom.xml
index 8d90340e..20c6bd0d 100644
--- a/99-integration/dubbo-samples-test-13560/pom.xml
+++ b/99-integration/dubbo-samples-test-13560/pom.xml
@@ -36,7 +36,7 @@
     <description>Dubbo Samples Test for 13560</description>
 
     <properties>
-        <dubbo.version>3.2.11-SNAPSHOT</dubbo.version>
+        <dubbo.version>3.2.11</dubbo.version>
         <junit5.version>5.9.2</junit5.version>
         <maven.compiler.source>1.8</maven.compiler.source>
         <maven.compiler.target>1.8</maven.compiler.target>
diff --git a/test/dubbo-test-runner/src/docker/Dockerfile 
b/test/dubbo-test-runner/src/docker/Dockerfile
index cb89c783..0be9df77 100644
--- a/test/dubbo-test-runner/src/docker/Dockerfile
+++ b/test/dubbo-test-runner/src/docker/Dockerfile
@@ -14,6 +14,8 @@
 #   limitations under the License.
 
 ARG JAVA_VER=8
+FROM openjdk:21-jdk-buster as mat-runtime
+
 FROM openjdk:${JAVA_VER}-jdk-buster
 
 ARG DEBIAN_MIRROR
@@ -24,7 +26,15 @@ RUN if [ -n "$DEBIAN_MIRROR" ]; then \
 
 RUN apt-get update && \
   apt-get install -y telnet && \
-  rm -rf /var/lib/apt/lists/*
+  rm -rf /var/lib/apt/lists/* && \
+  apt-get clean && \
+  ARCH=`arch` && \
+  wget 
https://download.eclipse.org/mat/1.15.0/rcp/MemoryAnalyzer-1.15.0.20231206-linux.gtk.${ARCH}.zip
 -O /tmp/mat.zip && \
+  unzip /tmp/mat.zip -d /tmp && \
+  mv /tmp/mat /usr/local/mat/ && \
+  rm -rf /tmp/mat.zip
+
+COPY --from=mat-runtime /usr/local/openjdk-21 /usr/local/mat-jdk
 
 VOLUME /usr/local/dubbo/app /usr/local/dubbo/logs
 
diff --git a/test/dubbo-test-runner/src/docker/run-dubbo-app.sh 
b/test/dubbo-test-runner/src/docker/run-dubbo-app.sh
index 12fda3f9..04c92b7b 100755
--- a/test/dubbo-test-runner/src/docker/run-dubbo-app.sh
+++ b/test/dubbo-test-runner/src/docker/run-dubbo-app.sh
@@ -29,7 +29,7 @@ fi
 
 echo "Running app : [$APP_MAIN_CLASS] ..."
 start=$SECONDS
-java $JAVA_OPTS $DEBUG_OPTS -cp "$APP_CLASSES_DIR:$APP_DEPENDENCY_DIR/*" 
$APP_MAIN_CLASS 2>&1 &
+java -server $JAVA_OPTS $DEBUG_OPTS -cp 
"$APP_CLASSES_DIR:$APP_DEPENDENCY_DIR/*" $APP_MAIN_CLASS 2>&1 &
 pid=$!
 
 echo "Wait for process to exit: $pid .."
diff --git a/test/dubbo-test-runner/src/docker/run-dubbo-test.sh 
b/test/dubbo-test-runner/src/docker/run-dubbo-test.sh
index 2ae882ed..100767d7 100755
--- a/test/dubbo-test-runner/src/docker/run-dubbo-test.sh
+++ b/test/dubbo-test-runner/src/docker/run-dubbo-test.sh
@@ -41,7 +41,7 @@ report_dir=$DIR/app/test-reports
 # Fix Class loading problem in java9+: CompletableFuture.supplyAsync() is 
executed in the ForkJoinWorkerThread
 # and it only uses system classloader to load classes instead of the 
IsolatedClassLoader
 
classpath=dubbo-test-runner.jar:$TEST_CLASSES_DIR:$APP_CLASSES_DIR:$APP_DEPENDENCY_DIR/*
-java $JAVA_OPTS $DEBUG_OPTS -cp $classpath 
org.apache.dubbo.test.runner.TestRunnerMain "$TEST_CLASSES_DIR" 
"$APP_CLASSES_DIR" "$APP_DEPENDENCY_DIR" "$report_dir" "$TEST_PATTERNS" 2>&1
+java -server $JAVA_OPTS $DEBUG_OPTS -cp $classpath 
org.apache.dubbo.test.runner.TestRunnerMain "$TEST_CLASSES_DIR" 
"$APP_CLASSES_DIR" "$APP_DEPENDENCY_DIR" "$report_dir" "$TEST_PATTERNS" 2>&1
 result=$?
 if [ $result -ne 0 ]; then
   echo "Run tests failure"

Reply via email to