You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by ke...@apache.org on 2021/08/09 14:08:39 UTC

[skywalking] 01/01: Pool metrics objects

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

kezhenxu94 pushed a commit to branch object-pool
in repository https://gitbox.apache.org/repos/asf/skywalking.git

commit 76b76611baee63668604ff631f0b0d25c26ff93d
Author: kezhenxu94 <ke...@apache.org>
AuthorDate: Mon Aug 9 22:08:21 2021 +0800

    Pool metrics objects
---
 .../datacarrier/consumer/BulkConsumePool.java      | 16 +++----
 .../skywalking/oap/meter/analyzer/Analyzer.java    |  5 +-
 .../exporter/provider/grpc/GRPCExporter.java       | 11 +++--
 .../exporter/provider/grpc/GRPCExporterTest.java   | 13 ++---
 .../server/exporter/provider/grpc/MockMetrics.java |  5 ++
 .../code-templates/dispatcher/doMetrics.ftl        |  2 +-
 .../metrics-builder/storage2Entity.ftl             |  4 +-
 .../resources/code-templates/metrics/toDay.ftl     |  4 +-
 .../resources/code-templates/metrics/toHour.ftl    |  4 +-
 .../core/alarm/provider/NotifyHandlerTest.java     |  4 +-
 .../core/alarm/provider/RunningRuleTest.java       | 41 +++++++++++++---
 .../oap/server/core/MetricsObjectPool.java         | 47 ++++++++++++++++++
 .../skywalking/oap/server/core/Recyclable.java     | 26 ++++++++++
 .../core/analysis/data/MergableBufferedData.java   |  4 +-
 .../analysis/manual/endpoint/EndpointTraffic.java  | 11 +++++
 .../analysis/manual/instance/InstanceTraffic.java  | 13 ++++-
 .../manual/networkalias/NetworkAddressAlias.java   | 13 ++++-
 .../endpoint/EndpointCallRelationDispatcher.java   |  3 +-
 .../EndpointRelationServerSideMetrics.java         | 18 +++++--
 .../ServiceInstanceCallRelationDispatcher.java     |  7 ++-
 .../ServiceInstanceRelationClientSideMetrics.java  | 46 +++++++++++++++---
 .../ServiceInstanceRelationServerSideMetrics.java  | 46 +++++++++++++++---
 .../service/ServiceCallRelationDispatcher.java     |  5 +-
 .../service/ServiceRelationClientSideMetrics.java  | 18 +++++--
 .../service/ServiceRelationServerSideMetrics.java  | 18 +++++--
 .../analysis/manual/service/ServiceTraffic.java    | 10 ++++
 .../server/core/analysis/meter/MeterSystem.java    |  8 ++--
 .../analysis/meter/function/HistogramFunction.java |  9 ++++
 .../meter/function/PercentileFunction.java         | 56 +++++++++++++++++-----
 .../analysis/meter/function/avg/AvgFunction.java   | 12 +++++
 .../meter/function/avg/AvgHistogramFunction.java   | 11 +++++
 .../avg/AvgHistogramPercentileFunction.java        | 14 ++++++
 .../meter/function/avg/AvgLabeledFunction.java     | 12 +++++
 .../meter/function/latest/LatestFunction.java      | 25 ++++++++--
 .../analysis/meter/function/sum/SumFunction.java   | 13 ++++-
 .../server/core/analysis/metrics/ApdexMetrics.java | 10 +++-
 .../server/core/analysis/metrics/CPMMetrics.java   |  9 ++++
 .../server/core/analysis/metrics/CountMetrics.java |  8 ++++
 .../server/core/analysis/metrics/DataTable.java    | 16 ++++++-
 .../core/analysis/metrics/DoubleAvgMetrics.java    | 11 +++++
 .../core/analysis/metrics/HistogramMetrics.java    |  8 ++++
 .../oap/server/core/analysis/metrics/IntList.java  | 16 ++++++-
 .../core/analysis/metrics/LongAvgMetrics.java      | 10 ++++
 .../core/analysis/metrics/MaxDoubleMetrics.java    |  8 ++++
 .../core/analysis/metrics/MaxLongMetrics.java      |  8 ++++
 .../oap/server/core/analysis/metrics/Metrics.java  | 11 ++++-
 .../core/analysis/metrics/MinDoubleMetrics.java    |  8 ++++
 .../core/analysis/metrics/MinLongMetrics.java      |  8 ++++
 .../core/analysis/metrics/PercentMetrics.java      | 10 ++++
 .../core/analysis/metrics/PercentileMetrics.java   | 11 +++++
 .../server/core/analysis/metrics/PxxMetrics.java   | 11 +++++
 .../server/core/analysis/metrics/RateMetrics.java  | 10 ++++
 .../server/core/analysis/metrics/SumMetrics.java   |  8 ++++
 .../server/core/analysis/worker/ExportWorker.java  |  4 +-
 .../analysis/worker/MetricsAggregateWorker.java    |  8 ++--
 .../analysis/worker/MetricsPersistentWorker.java   | 29 +++++++----
 .../analysis/worker/MetricsStreamProcessor.java    |  3 +-
 .../oap/server/core/exporter/ExportEvent.java      | 11 ++---
 .../core/remote/client/GRPCRemoteClient.java       |  5 ++
 .../skywalking/oap/server/core/source/Event.java   | 18 +++++++
 .../endpoint/EndpointCallRelationTest.java         | 13 +++--
 .../instance/ServiceInstanceRelationTest.java      | 25 ++++++----
 .../relation/service/ServiceRelationTest.java      | 25 ++++++----
 .../meter/function/HistogramFunctionTest.java      | 21 ++++----
 .../function/avg/AvgHistogramFunctionTest.java     | 21 ++++----
 .../core/analysis/metrics/LongAvgMetricsTest.java  |  9 ++--
 .../core/analysis/metrics/MaxLongMetricsTest.java  |  9 ++--
 .../server/core/analysis/metrics/MetricsTest.java  | 16 +++++--
 68 files changed, 774 insertions(+), 178 deletions(-)

diff --git a/apm-commons/apm-datacarrier/src/main/java/org/apache/skywalking/apm/commons/datacarrier/consumer/BulkConsumePool.java b/apm-commons/apm-datacarrier/src/main/java/org/apache/skywalking/apm/commons/datacarrier/consumer/BulkConsumePool.java
index 2d2195d..0f182a9 100644
--- a/apm-commons/apm-datacarrier/src/main/java/org/apache/skywalking/apm/commons/datacarrier/consumer/BulkConsumePool.java
+++ b/apm-commons/apm-datacarrier/src/main/java/org/apache/skywalking/apm/commons/datacarrier/consumer/BulkConsumePool.java
@@ -21,6 +21,7 @@ package org.apache.skywalking.apm.commons.datacarrier.consumer;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.Callable;
+import lombok.RequiredArgsConstructor;
 import org.apache.skywalking.apm.commons.datacarrier.EnvUtil;
 import org.apache.skywalking.apm.commons.datacarrier.buffer.Channels;
 
@@ -36,7 +37,7 @@ public class BulkConsumePool implements ConsumerPool {
 
     public BulkConsumePool(String name, int size, long consumeCycle) {
         size = EnvUtil.getInt(name + "_THREAD", size);
-        allConsumers = new ArrayList<MultipleChannelsConsumer>(size);
+        allConsumers = new ArrayList<>(size);
         for (int i = 0; i < size; i++) {
             MultipleChannelsConsumer multipleChannelsConsumer = new MultipleChannelsConsumer("DataCarrier." + name + ".BulkConsumePool." + i + ".Thread", consumeCycle);
             multipleChannelsConsumer.setDaemon(true);
@@ -95,16 +96,11 @@ public class BulkConsumePool implements ConsumerPool {
     /**
      * The creator for {@link BulkConsumePool}.
      */
+    @RequiredArgsConstructor
     public static class Creator implements Callable<ConsumerPool> {
-        private String name;
-        private int size;
-        private long consumeCycle;
-
-        public Creator(String name, int poolSize, long consumeCycle) {
-            this.name = name;
-            this.size = poolSize;
-            this.consumeCycle = consumeCycle;
-        }
+        private final String name;
+        private final int size;
+        private final long consumeCycle;
 
         @Override
         public ConsumerPool call() {
diff --git a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/Analyzer.java b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/Analyzer.java
index 5364b0c..37b0ef8 100644
--- a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/Analyzer.java
+++ b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/Analyzer.java
@@ -35,6 +35,7 @@ import org.apache.skywalking.oap.meter.analyzer.dsl.Result;
 import org.apache.skywalking.oap.meter.analyzer.dsl.Sample;
 import org.apache.skywalking.oap.meter.analyzer.dsl.SampleFamily;
 import org.apache.skywalking.oap.meter.analyzer.k8s.K8sInfoRegistry;
+import org.apache.skywalking.oap.server.core.MetricsObjectPool;
 import org.apache.skywalking.oap.server.core.analysis.NodeType;
 import org.apache.skywalking.oap.server.core.analysis.TimeBucket;
 import org.apache.skywalking.oap.server.core.analysis.manual.endpoint.EndpointTraffic;
@@ -285,7 +286,7 @@ public class Analyzer {
     }
 
     private void serverSide(MeterEntity entity) {
-        ServiceRelationServerSideMetrics metrics = new ServiceRelationServerSideMetrics();
+        ServiceRelationServerSideMetrics metrics = MetricsObjectPool.get(ServiceRelationServerSideMetrics.class);
         metrics.setTimeBucket(TimeBucket.getMinuteTimeBucket(System.currentTimeMillis()));
         metrics.setSourceServiceId(entity.sourceServiceId());
         metrics.setDestServiceId(entity.destServiceId());
@@ -295,7 +296,7 @@ public class Analyzer {
     }
 
     private void clientSide(MeterEntity entity) {
-        ServiceRelationClientSideMetrics metrics = new ServiceRelationClientSideMetrics();
+        ServiceRelationClientSideMetrics metrics = MetricsObjectPool.get(ServiceRelationClientSideMetrics.class);
         metrics.setTimeBucket(TimeBucket.getMinuteTimeBucket(System.currentTimeMillis()));
         metrics.setSourceServiceId(entity.sourceServiceId());
         metrics.setDestServiceId(entity.destServiceId());
diff --git a/oap-server/exporter/src/main/java/org/apache/skywalking/oap/server/exporter/provider/grpc/GRPCExporter.java b/oap-server/exporter/src/main/java/org/apache/skywalking/oap/server/exporter/provider/grpc/GRPCExporter.java
index 8758584..c209496 100644
--- a/oap-server/exporter/src/main/java/org/apache/skywalking/oap/server/exporter/provider/grpc/GRPCExporter.java
+++ b/oap-server/exporter/src/main/java/org/apache/skywalking/oap/server/exporter/provider/grpc/GRPCExporter.java
@@ -59,7 +59,7 @@ public class GRPCExporter extends MetricFormatter implements MetricValuesExportS
     private final GRPCExporterSetting setting;
     private final MetricExportServiceGrpc.MetricExportServiceStub exportServiceFutureStub;
     private final MetricExportServiceGrpc.MetricExportServiceBlockingStub blockingStub;
-    private final DataCarrier exportBuffer;
+    private final DataCarrier<ExportData> exportBuffer;
     private final ReentrantLock fetchListLock;
     private volatile List<SubscriptionMetric> subscriptionList;
     private volatile long lastFetchTimestamp = 0;
@@ -71,7 +71,7 @@ public class GRPCExporter extends MetricFormatter implements MetricValuesExportS
         ManagedChannel channel = client.getChannel();
         exportServiceFutureStub = MetricExportServiceGrpc.newStub(channel);
         blockingStub = MetricExportServiceGrpc.newBlockingStub(channel);
-        exportBuffer = new DataCarrier<ExportData>(setting.getBufferChannelNum(), setting.getBufferChannelSize());
+        exportBuffer = new DataCarrier<>(setting.getBufferChannelNum(), setting.getBufferChannelSize());
         exportBuffer.consume(this, 1, 200);
         subscriptionList = new ArrayList<>();
         fetchListLock = new ReentrantLock();
@@ -178,8 +178,9 @@ public class GRPCExporter extends MetricFormatter implements MetricValuesExportS
 
             MetricsMetaInfo meta = row.getMeta();
             builder.setMetricName(meta.getMetricsName());
-            builder.setEventType(
-                EventType.INCREMENT.equals(row.getEventType()) ? EventType.INCREMENT : EventType.TOTAL);
+            builder.setEventType(ExportEvent.EventType.INCREMENT == row.getEventType()
+                                     ? EventType.INCREMENT
+                                     : EventType.TOTAL);
             String entityName = getEntityName(meta);
             if (entityName == null) {
                 return;
@@ -191,6 +192,8 @@ public class GRPCExporter extends MetricFormatter implements MetricValuesExportS
 
             streamObserver.onNext(builder.build());
             exportNum.getAndIncrement();
+
+            metrics.recycle();
         });
 
         streamObserver.onCompleted();
diff --git a/oap-server/exporter/src/test/java/org/apache/skywalking/oap/server/exporter/provider/grpc/GRPCExporterTest.java b/oap-server/exporter/src/test/java/org/apache/skywalking/oap/server/exporter/provider/grpc/GRPCExporterTest.java
index de42ce7..b980f56 100644
--- a/oap-server/exporter/src/test/java/org/apache/skywalking/oap/server/exporter/provider/grpc/GRPCExporterTest.java
+++ b/oap-server/exporter/src/test/java/org/apache/skywalking/oap/server/exporter/provider/grpc/GRPCExporterTest.java
@@ -22,6 +22,7 @@ import io.grpc.testing.GrpcServerRule;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
+import org.apache.skywalking.oap.server.core.MetricsObjectPool;
 import org.apache.skywalking.oap.server.core.analysis.metrics.MetricsMetaInfo;
 import org.apache.skywalking.oap.server.core.analysis.metrics.WithMetadata;
 import org.apache.skywalking.oap.server.core.exporter.ExportData;
@@ -60,7 +61,7 @@ public class GRPCExporterTest {
 
     @Test
     public void export() {
-        ExportEvent event = new ExportEvent(new MockExporterMetrics(), ExportEvent.EventType.TOTAL);
+        ExportEvent event = new ExportEvent(MetricsObjectPool.get(MockExporterMetrics.class), ExportEvent.EventType.TOTAL);
         exporter.export(event);
     }
 
@@ -102,10 +103,10 @@ public class GRPCExporterTest {
 
     private List<ExportData> dataList() {
         List<ExportData> dataList = new LinkedList<>();
-        dataList.add(new ExportData(metaInfo, new MockMetrics(), INCREMENT));
-        dataList.add(new ExportData(metaInfo, new MockIntValueMetrics(), INCREMENT));
-        dataList.add(new ExportData(metaInfo, new MockLongValueMetrics(), INCREMENT));
-        dataList.add(new ExportData(metaInfo, new MockDoubleValueMetrics(), INCREMENT));
+        dataList.add(new ExportData(metaInfo, MetricsObjectPool.get(MockMetrics.class), INCREMENT));
+        dataList.add(new ExportData(metaInfo, MetricsObjectPool.get(MockIntValueMetrics.class), INCREMENT));
+        dataList.add(new ExportData(metaInfo, MetricsObjectPool.get(MockLongValueMetrics.class), INCREMENT));
+        dataList.add(new ExportData(metaInfo, MetricsObjectPool.get(MockDoubleValueMetrics.class), INCREMENT));
         return dataList;
     }
-}
\ No newline at end of file
+}
diff --git a/oap-server/exporter/src/test/java/org/apache/skywalking/oap/server/exporter/provider/grpc/MockMetrics.java b/oap-server/exporter/src/test/java/org/apache/skywalking/oap/server/exporter/provider/grpc/MockMetrics.java
index 6a55802..8da3c2d 100644
--- a/oap-server/exporter/src/test/java/org/apache/skywalking/oap/server/exporter/provider/grpc/MockMetrics.java
+++ b/oap-server/exporter/src/test/java/org/apache/skywalking/oap/server/exporter/provider/grpc/MockMetrics.java
@@ -62,4 +62,9 @@ public class MockMetrics extends Metrics {
     public RemoteData.Builder serialize() {
         return null;
     }
+
+    @Override
+    public void recycle() {
+        handle.recycle(this);
+    }
 }
diff --git a/oap-server/oal-rt/src/main/resources/code-templates/dispatcher/doMetrics.ftl b/oap-server/oal-rt/src/main/resources/code-templates/dispatcher/doMetrics.ftl
index 6312960..4521f1a 100644
--- a/oap-server/oal-rt/src/main/resources/code-templates/dispatcher/doMetrics.ftl
+++ b/oap-server/oal-rt/src/main/resources/code-templates/dispatcher/doMetrics.ftl
@@ -8,7 +8,7 @@ private void do${metricsName}(${sourcePackage}${sourceName} source) {
     </#list>
 </#if>
 
-${metricsClassPackage}${metricsName}Metrics metrics = new ${metricsClassPackage}${metricsName}Metrics();
+${metricsClassPackage}${metricsName}Metrics metrics = org.apache.skywalking.oap.server.core.MetricsObjectPool.get(${metricsClassPackage}${metricsName}Metrics.class);
 metrics.setTimeBucket(source.getTimeBucket());
 <#list fieldsFromSource as field>
     metrics.${field.fieldSetter}(source.${field.fieldGetter}());
diff --git a/oap-server/oal-rt/src/main/resources/code-templates/metrics-builder/storage2Entity.ftl b/oap-server/oal-rt/src/main/resources/code-templates/metrics-builder/storage2Entity.ftl
index e8f71c9..577b53f 100644
--- a/oap-server/oal-rt/src/main/resources/code-templates/metrics-builder/storage2Entity.ftl
+++ b/oap-server/oal-rt/src/main/resources/code-templates/metrics-builder/storage2Entity.ftl
@@ -1,5 +1,5 @@
 public org.apache.skywalking.oap.server.core.storage.StorageData storage2Entity(java.util.Map dbMap) {
-${metricsClassPackage}${metricsName}Metrics metrics = new ${metricsClassPackage}${metricsName}Metrics();
+${metricsClassPackage}${metricsName}Metrics metrics = org.apache.skywalking.oap.server.core.MetricsObjectPool.get(${metricsClassPackage}${metricsName}Metrics.class);
 <#list fieldsFromSource as field>
     <#if field.typeName == "long" || field.typeName == "int" || field.typeName == "double" || field.typeName == "float">
         metrics.${field.fieldSetter}(((Number)dbMap.get("${field.columnName}")).${field.typeName}Value());
@@ -19,4 +19,4 @@ ${metricsClassPackage}${metricsName}Metrics metrics = new ${metricsClassPackage}
     </#if>
 </#list>
 return metrics;
-}
\ No newline at end of file
+}
diff --git a/oap-server/oal-rt/src/main/resources/code-templates/metrics/toDay.ftl b/oap-server/oal-rt/src/main/resources/code-templates/metrics/toDay.ftl
index e3c5bf9..ea516f7 100644
--- a/oap-server/oal-rt/src/main/resources/code-templates/metrics/toDay.ftl
+++ b/oap-server/oal-rt/src/main/resources/code-templates/metrics/toDay.ftl
@@ -1,5 +1,5 @@
 public org.apache.skywalking.oap.server.core.analysis.metrics.Metrics toDay() {
-${metricsClassPackage}${metricsName}Metrics metrics = new ${metricsClassPackage}${metricsName}Metrics();
+${metricsClassPackage}${metricsName}Metrics metrics = org.apache.skywalking.oap.server.core.MetricsObjectPool.get(${metricsClassPackage}${metricsName}Metrics.class);
 <#list fieldsFromSource as field>
     <#if field.columnName == "time_bucket">
         metrics.setTimeBucket(toTimeBucketInDay());
@@ -23,4 +23,4 @@ ${metricsClassPackage}${metricsName}Metrics metrics = new ${metricsClassPackage}
     </#if>
 </#list>
 return metrics;
-}
\ No newline at end of file
+}
diff --git a/oap-server/oal-rt/src/main/resources/code-templates/metrics/toHour.ftl b/oap-server/oal-rt/src/main/resources/code-templates/metrics/toHour.ftl
index b0bddbd..e1d2b3b 100644
--- a/oap-server/oal-rt/src/main/resources/code-templates/metrics/toHour.ftl
+++ b/oap-server/oal-rt/src/main/resources/code-templates/metrics/toHour.ftl
@@ -1,5 +1,5 @@
 public org.apache.skywalking.oap.server.core.analysis.metrics.Metrics toHour() {
-${metricsClassPackage}${metricsName}Metrics metrics = new ${metricsClassPackage}${metricsName}Metrics();
+${metricsClassPackage}${metricsName}Metrics metrics = org.apache.skywalking.oap.server.core.MetricsObjectPool.get(${metricsClassPackage}${metricsName}Metrics.class);
 <#list fieldsFromSource as field>
     <#if field.columnName == "time_bucket">
         metrics.setTimeBucket(toTimeBucketInHour());
@@ -23,4 +23,4 @@ ${metricsClassPackage}${metricsName}Metrics metrics = new ${metricsClassPackage}
     </#if>
 </#list>
 return metrics;
-}
\ No newline at end of file
+}
diff --git a/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/NotifyHandlerTest.java b/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/NotifyHandlerTest.java
index 4d252e0..28ac029 100644
--- a/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/NotifyHandlerTest.java
+++ b/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/NotifyHandlerTest.java
@@ -309,7 +309,7 @@ public class NotifyHandlerTest {
         Whitebox.setInternalState(notifyHandler, "core", core);
     }
 
-    private abstract class MockMetrics extends Metrics implements WithMetadata {
+    private abstract static class MockMetrics extends Metrics implements WithMetadata {
 
     }
-}
\ No newline at end of file
+}
diff --git a/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/RunningRuleTest.java b/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/RunningRuleTest.java
index 2802722..8c9ed1e 100644
--- a/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/RunningRuleTest.java
+++ b/oap-server/server-alarm-plugin/src/test/java/org/apache/skywalking/oap/server/core/alarm/provider/RunningRuleTest.java
@@ -27,6 +27,7 @@ import java.util.Objects;
 import lombok.Getter;
 import lombok.Setter;
 import org.apache.skywalking.oap.server.core.Const;
+import org.apache.skywalking.oap.server.core.MetricsObjectPool;
 import org.apache.skywalking.oap.server.core.alarm.AlarmCallback;
 import org.apache.skywalking.oap.server.core.alarm.AlarmMessage;
 import org.apache.skywalking.oap.server.core.alarm.MetaInAlarm;
@@ -50,7 +51,7 @@ import org.powermock.reflect.Whitebox;
  * So in this test, we need to simulate a lot of scenario to see the reactions.
  */
 public class RunningRuleTest {
-    private static DateTimeFormatter TIME_BUCKET_FORMATTER = DateTimeFormat.forPattern("yyyyMMddHHmm");
+    private static final DateTimeFormatter TIME_BUCKET_FORMATTER = DateTimeFormat.forPattern("yyyyMMddHHmm");
 
     @Test
     public void testInitAndStart() {
@@ -404,14 +405,15 @@ public class RunningRuleTest {
     }
 
     private Metrics getMetrics(long timeBucket, int value) {
-        MockMetrics mockMetrics = new MockMetrics();
+        MockMetrics mockMetrics = MetricsObjectPool.get(MockMetrics.class);
         mockMetrics.setValue(value);
         mockMetrics.setTimeBucket(timeBucket);
         return mockMetrics;
     }
 
     private Metrics getMultipleValueMetrics(long timeBucket, int... values) {
-        MockMultipleValueMetrics mockMultipleValueMetrics = new MockMultipleValueMetrics();
+        MockMultipleValueMetrics mockMultipleValueMetrics =
+            MetricsObjectPool.get(MockMultipleValueMetrics.class);
         mockMultipleValueMetrics.setValues(values);
         mockMultipleValueMetrics.setTimeBucket(timeBucket);
         return mockMultipleValueMetrics;
@@ -419,13 +421,14 @@ public class RunningRuleTest {
     }
 
     private Metrics getLabeledValueMetrics(long timeBucket, String values) {
-        MockLabeledValueMetrics mockLabeledValueMetrics = new MockLabeledValueMetrics();
+        MockLabeledValueMetrics mockLabeledValueMetrics =
+            MetricsObjectPool.get(MockLabeledValueMetrics.class);
         mockLabeledValueMetrics.setValue(new DataTable(values));
         mockLabeledValueMetrics.setTimeBucket(timeBucket);
         return mockLabeledValueMetrics;
     }
 
-    private class MockMetrics extends Metrics implements IntValueHolder {
+    public static class MockMetrics extends Metrics implements IntValueHolder {
         private int value;
 
         @Override
@@ -476,9 +479,17 @@ public class RunningRuleTest {
         public int remoteHashCode() {
             return 0;
         }
+
+        @Override
+        public void recycle() {
+            this.value = 0;
+            setTimeBucket(0);
+            setLastUpdateTimestamp(0);
+            handle.recycle(this);
+        }
     }
 
-    private class MockMultipleValueMetrics extends Metrics implements MultiIntValuesHolder {
+    public static class MockMultipleValueMetrics extends Metrics implements MultiIntValuesHolder {
         private int[] values;
 
         public void setValues(int[] values) {
@@ -529,9 +540,17 @@ public class RunningRuleTest {
         public RemoteData.Builder serialize() {
             return null;
         }
+
+        @Override
+        public void recycle() {
+            this.values = null;
+            setTimeBucket(0);
+            setLastUpdateTimestamp(0);
+            handle.recycle(this);
+        }
     }
 
-    private class MockLabeledValueMetrics extends Metrics implements LabeledValueHolder {
+    public static class MockLabeledValueMetrics extends Metrics implements LabeledValueHolder {
 
         @Getter
         @Setter
@@ -576,6 +595,14 @@ public class RunningRuleTest {
         public RemoteData.Builder serialize() {
             return null;
         }
+
+        @Override
+        public void recycle() {
+            this.value.recycle();
+            setTimeBucket(0);
+            setLastUpdateTimestamp(0);
+            handle.recycle(this);
+        }
     }
 
     private void assertLabeled(AlarmRule alarmRule) {
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/MetricsObjectPool.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/MetricsObjectPool.java
new file mode 100644
index 0000000..d6a3966
--- /dev/null
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/MetricsObjectPool.java
@@ -0,0 +1,47 @@
+/*
+ * 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.skywalking.oap.server.core;
+
+import io.netty.util.internal.ObjectPool;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics;
+
+@Slf4j
+public final class MetricsObjectPool {
+    private static final Map<Class<? extends Metrics>, ObjectPool<Metrics>> POOLS =
+        new ConcurrentHashMap<>();
+
+    @SuppressWarnings("unchecked")
+    public static <T extends Metrics> T get(Class<T> type) {
+        final ObjectPool<Metrics> pool = POOLS.computeIfAbsent(type, __ -> ObjectPool.newPool(
+            handle -> {
+                try {
+                    final Metrics m = type.getDeclaredConstructor().newInstance();
+                    m.handle(handle);
+                    return m;
+                } catch (Exception e) {
+                    log.error("Failed to create object for {}", type, e);
+                    throw new RuntimeException(e);
+                }
+            })
+        );
+        return (T) pool.get();
+    }
+}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/Recyclable.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/Recyclable.java
new file mode 100644
index 0000000..6b50c48
--- /dev/null
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/Recyclable.java
@@ -0,0 +1,26 @@
+/*
+ * 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.skywalking.oap.server.core;
+
+import io.netty.util.internal.ObjectPool;
+
+public interface Recyclable<T> {
+    void handle(ObjectPool.Handle<T> handle);
+
+    void recycle();
+}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/data/MergableBufferedData.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/data/MergableBufferedData.java
index 501135d..687d891 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/data/MergableBufferedData.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/data/MergableBufferedData.java
@@ -18,10 +18,10 @@
 
 package org.apache.skywalking.oap.server.core.analysis.data;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.stream.Collectors;
 import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics;
 
 /**
@@ -61,7 +61,7 @@ public class MergableBufferedData<METRICS extends Metrics> implements BufferedDa
     @Override
     public List<METRICS> read() {
         try {
-            return buffer.values().stream().collect(Collectors.toList());
+            return new ArrayList<>(buffer.values());
         } finally {
             buffer.clear();
         }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/EndpointTraffic.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/EndpointTraffic.java
index e302904..05355f9 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/EndpointTraffic.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/EndpointTraffic.java
@@ -44,12 +44,14 @@ public class EndpointTraffic extends Metrics {
     public static final String INDEX_NAME = "endpoint_traffic";
 
     public static final String SERVICE_ID = "service_id";
+
     public static final String NAME = "name";
 
     @Setter
     @Getter
     @Column(columnName = SERVICE_ID)
     private String serviceId;
+
     @Setter
     @Getter
     @Column(columnName = NAME, matchQuery = true)
@@ -86,6 +88,15 @@ public class EndpointTraffic extends Metrics {
         return hashCode();
     }
 
+    @Override
+    public void recycle() {
+        this.serviceId = null;
+        this.name = Const.EMPTY_STRING;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
+
     public static class Builder implements StorageHashMapBuilder<EndpointTraffic> {
 
         @Override
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/instance/InstanceTraffic.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/instance/InstanceTraffic.java
index e66595b..0f972a2 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/instance/InstanceTraffic.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/instance/InstanceTraffic.java
@@ -79,7 +79,7 @@ public class InstanceTraffic extends Metrics {
         if (instanceTraffic.getProperties() != null && instanceTraffic.getProperties().size() > 0) {
             this.properties = instanceTraffic.getProperties();
         }
-        /**
+        /*
          * Keep the time bucket as the same time inserted.
          */
         if (this.getTimeBucket() > metrics.getTimeBucket()) {
@@ -125,6 +125,17 @@ public class InstanceTraffic extends Metrics {
         return IDManager.ServiceInstanceID.buildId(serviceId, name);
     }
 
+    @Override
+    public void recycle() {
+        this.serviceId = null;
+        this.name = null;
+        this.lastPingTimestamp = 0;
+        this.properties = null;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
+
     public static class Builder implements StorageHashMapBuilder<InstanceTraffic> {
         @Override
         public InstanceTraffic storage2Entity(final Map<String, Object> dbMap) {
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/networkalias/NetworkAddressAlias.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/networkalias/NetworkAddressAlias.java
index 75b3ff7..964f7f6 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/networkalias/NetworkAddressAlias.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/networkalias/NetworkAddressAlias.java
@@ -72,7 +72,7 @@ public class NetworkAddressAlias extends Metrics {
         this.representServiceId = alias.getRepresentServiceId();
         this.representServiceInstanceId = alias.getRepresentServiceInstanceId();
         this.lastUpdateTimeBucket = alias.getLastUpdateTimeBucket();
-        /**
+        /*
          * Keep the time bucket as the same time inserted.
          */
         if (this.getTimeBucket() > metrics.getTimeBucket()) {
@@ -113,6 +113,17 @@ public class NetworkAddressAlias extends Metrics {
         return builder;
     }
 
+    @Override
+    public void recycle() {
+        this.address = null;
+        this.representServiceId = null;
+        this.representServiceInstanceId = null;
+        this.lastUpdateTimeBucket = 0;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
+
     public static class Builder implements StorageHashMapBuilder<NetworkAddressAlias> {
         @Override
         public NetworkAddressAlias storage2Entity(final Map<String, Object> dbMap) {
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/endpoint/EndpointCallRelationDispatcher.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/endpoint/EndpointCallRelationDispatcher.java
index 562b27e..5f162f1 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/endpoint/EndpointCallRelationDispatcher.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/endpoint/EndpointCallRelationDispatcher.java
@@ -18,6 +18,7 @@
 
 package org.apache.skywalking.oap.server.core.analysis.manual.relation.endpoint;
 
+import org.apache.skywalking.oap.server.core.MetricsObjectPool;
 import org.apache.skywalking.oap.server.core.analysis.IDManager;
 import org.apache.skywalking.oap.server.core.analysis.SourceDispatcher;
 import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor;
@@ -35,7 +36,7 @@ public class EndpointCallRelationDispatcher implements SourceDispatcher<Endpoint
     }
 
     private void serverSide(EndpointRelation source) {
-        EndpointRelationServerSideMetrics metrics = new EndpointRelationServerSideMetrics();
+        EndpointRelationServerSideMetrics metrics = MetricsObjectPool.get(EndpointRelationServerSideMetrics.class);
         metrics.setTimeBucket(source.getTimeBucket());
         metrics.setSourceEndpoint(
             IDManager.EndpointID.buildId(source.getServiceId(), source.getEndpoint()));
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/endpoint/EndpointRelationServerSideMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/endpoint/EndpointRelationServerSideMetrics.java
index 1feb1af..4be9f8f 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/endpoint/EndpointRelationServerSideMetrics.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/endpoint/EndpointRelationServerSideMetrics.java
@@ -24,6 +24,7 @@ import lombok.EqualsAndHashCode;
 import lombok.Getter;
 import lombok.Setter;
 import org.apache.skywalking.oap.server.core.Const;
+import org.apache.skywalking.oap.server.core.MetricsObjectPool;
 import org.apache.skywalking.oap.server.core.analysis.Stream;
 import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics;
 import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor;
@@ -80,7 +81,7 @@ public class EndpointRelationServerSideMetrics extends Metrics {
 
     @Override
     public Metrics toHour() {
-        EndpointRelationServerSideMetrics metrics = new EndpointRelationServerSideMetrics();
+        EndpointRelationServerSideMetrics metrics = MetricsObjectPool.get(EndpointRelationServerSideMetrics.class);
         metrics.setTimeBucket(toTimeBucketInHour());
         metrics.setSourceEndpoint(getSourceEndpoint());
         metrics.setDestEndpoint(getDestEndpoint());
@@ -91,7 +92,7 @@ public class EndpointRelationServerSideMetrics extends Metrics {
 
     @Override
     public Metrics toDay() {
-        EndpointRelationServerSideMetrics metrics = new EndpointRelationServerSideMetrics();
+        EndpointRelationServerSideMetrics metrics = MetricsObjectPool.get(EndpointRelationServerSideMetrics.class);
         metrics.setTimeBucket(toTimeBucketInDay());
         metrics.setSourceEndpoint(getSourceEndpoint());
         metrics.setDestEndpoint(getDestEndpoint());
@@ -132,11 +133,22 @@ public class EndpointRelationServerSideMetrics extends Metrics {
         return remoteBuilder;
     }
 
+    @Override
+    public void recycle() {
+        this.sourceEndpoint = null;
+        this.destEndpoint = null;
+        this.componentId = 0;
+        this.entityId = null;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
+
     public static class Builder implements StorageHashMapBuilder<EndpointRelationServerSideMetrics> {
 
         @Override
         public EndpointRelationServerSideMetrics storage2Entity(Map<String, Object> dbMap) {
-            EndpointRelationServerSideMetrics metrics = new EndpointRelationServerSideMetrics();
+            EndpointRelationServerSideMetrics metrics = MetricsObjectPool.get(EndpointRelationServerSideMetrics.class);
             metrics.setSourceEndpoint((String) dbMap.get(SOURCE_ENDPOINT));
             metrics.setDestEndpoint((String) dbMap.get(DEST_ENDPOINT));
             metrics.setComponentId(((Number) dbMap.get(COMPONENT_ID)).intValue());
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/instance/ServiceInstanceCallRelationDispatcher.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/instance/ServiceInstanceCallRelationDispatcher.java
index 19fd61a..c086fb9 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/instance/ServiceInstanceCallRelationDispatcher.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/instance/ServiceInstanceCallRelationDispatcher.java
@@ -18,6 +18,7 @@
 
 package org.apache.skywalking.oap.server.core.analysis.manual.relation.instance;
 
+import org.apache.skywalking.oap.server.core.MetricsObjectPool;
 import org.apache.skywalking.oap.server.core.analysis.SourceDispatcher;
 import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor;
 import org.apache.skywalking.oap.server.core.source.ServiceInstanceRelation;
@@ -37,7 +38,8 @@ public class ServiceInstanceCallRelationDispatcher implements SourceDispatcher<S
     }
 
     private void serverSide(ServiceInstanceRelation source) {
-        ServiceInstanceRelationServerSideMetrics metrics = new ServiceInstanceRelationServerSideMetrics();
+        ServiceInstanceRelationServerSideMetrics metrics =
+            MetricsObjectPool.get(ServiceInstanceRelationServerSideMetrics.class);
         metrics.setTimeBucket(source.getTimeBucket());
         metrics.setSourceServiceId(source.getSourceServiceId());
         metrics.setSourceServiceInstanceId(source.getSourceServiceInstanceId());
@@ -49,7 +51,8 @@ public class ServiceInstanceCallRelationDispatcher implements SourceDispatcher<S
     }
 
     private void clientSide(ServiceInstanceRelation source) {
-        ServiceInstanceRelationClientSideMetrics metrics = new ServiceInstanceRelationClientSideMetrics();
+        ServiceInstanceRelationClientSideMetrics metrics =
+            MetricsObjectPool.get(ServiceInstanceRelationClientSideMetrics.class);
         metrics.setTimeBucket(source.getTimeBucket());
         metrics.setSourceServiceId(source.getSourceServiceId());
         metrics.setSourceServiceInstanceId(source.getSourceServiceInstanceId());
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/instance/ServiceInstanceRelationClientSideMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/instance/ServiceInstanceRelationClientSideMetrics.java
index 1a49b98..d2ff768 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/instance/ServiceInstanceRelationClientSideMetrics.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/instance/ServiceInstanceRelationClientSideMetrics.java
@@ -24,6 +24,7 @@ import lombok.EqualsAndHashCode;
 import lombok.Getter;
 import lombok.Setter;
 import org.apache.skywalking.oap.server.core.Const;
+import org.apache.skywalking.oap.server.core.MetricsObjectPool;
 import org.apache.skywalking.oap.server.core.analysis.Stream;
 import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics;
 import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor;
@@ -32,40 +33,53 @@ import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine;
 import org.apache.skywalking.oap.server.core.storage.StorageHashMapBuilder;
 import org.apache.skywalking.oap.server.core.storage.annotation.Column;
 
-@Stream(name = ServiceInstanceRelationClientSideMetrics.INDEX_NAME, scopeId = DefaultScopeDefine.SERVICE_INSTANCE_RELATION,
-    builder = ServiceInstanceRelationClientSideMetrics.Builder.class, processor = MetricsStreamProcessor.class)
+@Stream(
+    name = ServiceInstanceRelationClientSideMetrics.INDEX_NAME,
+    scopeId = DefaultScopeDefine.SERVICE_INSTANCE_RELATION,
+    builder = ServiceInstanceRelationClientSideMetrics.Builder.class,
+    processor = MetricsStreamProcessor.class)
 @EqualsAndHashCode(of = {
     "entityId"
 }, callSuper = true)
 public class ServiceInstanceRelationClientSideMetrics extends Metrics {
 
     public static final String INDEX_NAME = "service_instance_relation_client_side";
+
     public static final String SOURCE_SERVICE_ID = "source_service_id";
+
     public static final String SOURCE_SERVICE_INSTANCE_ID = "source_service_instance_id";
+
     public static final String DEST_SERVICE_ID = "dest_service_id";
+
     public static final String DEST_SERVICE_INSTANCE_ID = "dest_service_instance_id";
+
     public static final String COMPONENT_ID = "component_id";
 
     @Setter
     @Getter
     @Column(columnName = SOURCE_SERVICE_ID)
     private String sourceServiceId;
+
     @Setter
     @Getter
     @Column(columnName = SOURCE_SERVICE_INSTANCE_ID)
     private String sourceServiceInstanceId;
+
     @Setter
     @Getter
     @Column(columnName = DEST_SERVICE_ID)
     private String destServiceId;
+
     @Setter
     @Getter
     @Column(columnName = DEST_SERVICE_INSTANCE_ID)
     private String destServiceInstanceId;
+
     @Setter
     @Getter
     @Column(columnName = COMPONENT_ID, storageOnly = true)
     private int componentId;
+
     @Setter
     @Getter
     @Column(columnName = ENTITY_ID, length = 512)
@@ -88,7 +102,8 @@ public class ServiceInstanceRelationClientSideMetrics extends Metrics {
 
     @Override
     public Metrics toHour() {
-        ServiceInstanceRelationClientSideMetrics metrics = new ServiceInstanceRelationClientSideMetrics();
+        ServiceInstanceRelationClientSideMetrics metrics =
+            MetricsObjectPool.get(ServiceInstanceRelationClientSideMetrics.class);
         metrics.setTimeBucket(toTimeBucketInHour());
         metrics.setSourceServiceId(getSourceServiceId());
         metrics.setSourceServiceInstanceId(getSourceServiceInstanceId());
@@ -101,7 +116,8 @@ public class ServiceInstanceRelationClientSideMetrics extends Metrics {
 
     @Override
     public Metrics toDay() {
-        ServiceInstanceRelationClientSideMetrics metrics = new ServiceInstanceRelationClientSideMetrics();
+        ServiceInstanceRelationClientSideMetrics metrics =
+            MetricsObjectPool.get(ServiceInstanceRelationClientSideMetrics.class);
         metrics.setTimeBucket(toTimeBucketInDay());
         metrics.setSourceServiceId(getSourceServiceId());
         metrics.setSourceServiceInstanceId(getSourceServiceInstanceId());
@@ -148,11 +164,26 @@ public class ServiceInstanceRelationClientSideMetrics extends Metrics {
         return remoteBuilder;
     }
 
-    public static class Builder implements StorageHashMapBuilder<ServiceInstanceRelationClientSideMetrics> {
+    @Override
+    public void recycle() {
+        this.sourceServiceId = null;
+        this.sourceServiceInstanceId = null;
+        this.destServiceId = null;
+        this.destServiceInstanceId = null;
+        this.componentId = 0;
+        this.entityId = null;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
+
+    public static class Builder
+        implements StorageHashMapBuilder<ServiceInstanceRelationClientSideMetrics> {
 
         @Override
         public ServiceInstanceRelationClientSideMetrics storage2Entity(Map<String, Object> dbMap) {
-            ServiceInstanceRelationClientSideMetrics metrics = new ServiceInstanceRelationClientSideMetrics();
+            ServiceInstanceRelationClientSideMetrics metrics =
+                MetricsObjectPool.get(ServiceInstanceRelationClientSideMetrics.class);
             metrics.setEntityId((String) dbMap.get(ENTITY_ID));
             metrics.setSourceServiceId((String) dbMap.get(SOURCE_SERVICE_ID));
             metrics.setSourceServiceInstanceId((String) dbMap.get(SOURCE_SERVICE_INSTANCE_ID));
@@ -164,7 +195,8 @@ public class ServiceInstanceRelationClientSideMetrics extends Metrics {
         }
 
         @Override
-        public Map<String, Object> entity2Storage(ServiceInstanceRelationClientSideMetrics storageData) {
+        public Map<String, Object> entity2Storage(
+            ServiceInstanceRelationClientSideMetrics storageData) {
             Map<String, Object> map = new HashMap<>();
             map.put(ENTITY_ID, storageData.getEntityId());
             map.put(SOURCE_SERVICE_ID, storageData.getSourceServiceId());
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/instance/ServiceInstanceRelationServerSideMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/instance/ServiceInstanceRelationServerSideMetrics.java
index 97fc99d..a21723b 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/instance/ServiceInstanceRelationServerSideMetrics.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/instance/ServiceInstanceRelationServerSideMetrics.java
@@ -24,6 +24,7 @@ import lombok.EqualsAndHashCode;
 import lombok.Getter;
 import lombok.Setter;
 import org.apache.skywalking.oap.server.core.Const;
+import org.apache.skywalking.oap.server.core.MetricsObjectPool;
 import org.apache.skywalking.oap.server.core.analysis.Stream;
 import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics;
 import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor;
@@ -32,40 +33,53 @@ import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine;
 import org.apache.skywalking.oap.server.core.storage.StorageHashMapBuilder;
 import org.apache.skywalking.oap.server.core.storage.annotation.Column;
 
-@Stream(name = ServiceInstanceRelationServerSideMetrics.INDEX_NAME, scopeId = DefaultScopeDefine.SERVICE_INSTANCE_RELATION,
-    builder = ServiceInstanceRelationServerSideMetrics.Builder.class, processor = MetricsStreamProcessor.class)
+@Stream(
+    name = ServiceInstanceRelationServerSideMetrics.INDEX_NAME,
+    scopeId = DefaultScopeDefine.SERVICE_INSTANCE_RELATION,
+    builder = ServiceInstanceRelationServerSideMetrics.Builder.class,
+    processor = MetricsStreamProcessor.class)
 @EqualsAndHashCode(of = {
     "entityId"
 }, callSuper = true)
 public class ServiceInstanceRelationServerSideMetrics extends Metrics {
 
     public static final String INDEX_NAME = "service_instance_relation_server_side";
+
     public static final String SOURCE_SERVICE_ID = "source_service_id";
+
     public static final String SOURCE_SERVICE_INSTANCE_ID = "source_service_instance_id";
+
     public static final String DEST_SERVICE_ID = "dest_service_id";
+
     public static final String DEST_SERVICE_INSTANCE_ID = "dest_service_instance_id";
+
     public static final String COMPONENT_ID = "component_id";
 
     @Setter
     @Getter
     @Column(columnName = SOURCE_SERVICE_ID)
     private String sourceServiceId;
+
     @Setter
     @Getter
     @Column(columnName = SOURCE_SERVICE_INSTANCE_ID)
     private String sourceServiceInstanceId;
+
     @Setter
     @Getter
     @Column(columnName = DEST_SERVICE_ID)
     private String destServiceId;
+
     @Setter
     @Getter
     @Column(columnName = DEST_SERVICE_INSTANCE_ID)
     private String destServiceInstanceId;
+
     @Setter
     @Getter
     @Column(columnName = COMPONENT_ID, storageOnly = true)
     private int componentId;
+
     @Setter
     @Getter
     @Column(columnName = ENTITY_ID, length = 512)
@@ -88,7 +102,8 @@ public class ServiceInstanceRelationServerSideMetrics extends Metrics {
 
     @Override
     public Metrics toHour() {
-        ServiceInstanceRelationServerSideMetrics metrics = new ServiceInstanceRelationServerSideMetrics();
+        ServiceInstanceRelationServerSideMetrics metrics =
+            MetricsObjectPool.get(ServiceInstanceRelationServerSideMetrics.class);
         metrics.setTimeBucket(toTimeBucketInHour());
         metrics.setSourceServiceId(getSourceServiceId());
         metrics.setSourceServiceInstanceId(getSourceServiceInstanceId());
@@ -101,7 +116,8 @@ public class ServiceInstanceRelationServerSideMetrics extends Metrics {
 
     @Override
     public Metrics toDay() {
-        ServiceInstanceRelationServerSideMetrics metrics = new ServiceInstanceRelationServerSideMetrics();
+        ServiceInstanceRelationServerSideMetrics metrics =
+            MetricsObjectPool.get(ServiceInstanceRelationServerSideMetrics.class);
         metrics.setTimeBucket(toTimeBucketInDay());
         metrics.setSourceServiceId(getSourceServiceId());
         metrics.setSourceServiceInstanceId(getSourceServiceInstanceId());
@@ -148,11 +164,26 @@ public class ServiceInstanceRelationServerSideMetrics extends Metrics {
         return remoteBuilder;
     }
 
-    public static class Builder implements StorageHashMapBuilder<ServiceInstanceRelationServerSideMetrics> {
+    @Override
+    public void recycle() {
+        this.sourceServiceId = null;
+        this.sourceServiceInstanceId = null;
+        this.destServiceId = null;
+        this.destServiceInstanceId = null;
+        this.componentId = 0;
+        this.entityId = null;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
+
+    public static class Builder
+        implements StorageHashMapBuilder<ServiceInstanceRelationServerSideMetrics> {
 
         @Override
         public ServiceInstanceRelationServerSideMetrics storage2Entity(Map<String, Object> dbMap) {
-            ServiceInstanceRelationServerSideMetrics metrics = new ServiceInstanceRelationServerSideMetrics();
+            ServiceInstanceRelationServerSideMetrics metrics =
+                MetricsObjectPool.get(ServiceInstanceRelationServerSideMetrics.class);
             metrics.setEntityId((String) dbMap.get(ENTITY_ID));
             metrics.setSourceServiceId((String) dbMap.get(SOURCE_SERVICE_ID));
             metrics.setSourceServiceInstanceId((String) dbMap.get(SOURCE_SERVICE_INSTANCE_ID));
@@ -164,7 +195,8 @@ public class ServiceInstanceRelationServerSideMetrics extends Metrics {
         }
 
         @Override
-        public Map<String, Object> entity2Storage(ServiceInstanceRelationServerSideMetrics storageData) {
+        public Map<String, Object> entity2Storage(
+            ServiceInstanceRelationServerSideMetrics storageData) {
             Map<String, Object> map = new HashMap<>();
             map.put(ENTITY_ID, storageData.getEntityId());
             map.put(SOURCE_SERVICE_ID, storageData.getSourceServiceId());
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceCallRelationDispatcher.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceCallRelationDispatcher.java
index 867f546..d609bb3 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceCallRelationDispatcher.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceCallRelationDispatcher.java
@@ -18,6 +18,7 @@
 
 package org.apache.skywalking.oap.server.core.analysis.manual.relation.service;
 
+import org.apache.skywalking.oap.server.core.MetricsObjectPool;
 import org.apache.skywalking.oap.server.core.analysis.SourceDispatcher;
 import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor;
 import org.apache.skywalking.oap.server.core.source.ServiceRelation;
@@ -37,7 +38,7 @@ public class ServiceCallRelationDispatcher implements SourceDispatcher<ServiceRe
     }
 
     private void serverSide(ServiceRelation source) {
-        ServiceRelationServerSideMetrics metrics = new ServiceRelationServerSideMetrics();
+        ServiceRelationServerSideMetrics metrics = MetricsObjectPool.get(ServiceRelationServerSideMetrics.class);
         metrics.setTimeBucket(source.getTimeBucket());
         metrics.setSourceServiceId(source.getSourceServiceId());
         metrics.setDestServiceId(source.getDestServiceId());
@@ -47,7 +48,7 @@ public class ServiceCallRelationDispatcher implements SourceDispatcher<ServiceRe
     }
 
     private void clientSide(ServiceRelation source) {
-        ServiceRelationClientSideMetrics metrics = new ServiceRelationClientSideMetrics();
+        ServiceRelationClientSideMetrics metrics = MetricsObjectPool.get(ServiceRelationClientSideMetrics.class);
         metrics.setTimeBucket(source.getTimeBucket());
         metrics.setSourceServiceId(source.getSourceServiceId());
         metrics.setDestServiceId(source.getDestServiceId());
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceRelationClientSideMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceRelationClientSideMetrics.java
index 4bacf15..e8d02c8 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceRelationClientSideMetrics.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceRelationClientSideMetrics.java
@@ -24,6 +24,7 @@ import lombok.EqualsAndHashCode;
 import lombok.Getter;
 import lombok.Setter;
 import org.apache.skywalking.oap.server.core.Const;
+import org.apache.skywalking.oap.server.core.MetricsObjectPool;
 import org.apache.skywalking.oap.server.core.analysis.Stream;
 import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics;
 import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor;
@@ -85,7 +86,7 @@ public class ServiceRelationClientSideMetrics extends Metrics {
 
     @Override
     public Metrics toHour() {
-        ServiceRelationClientSideMetrics metrics = new ServiceRelationClientSideMetrics();
+        ServiceRelationClientSideMetrics metrics = MetricsObjectPool.get(ServiceRelationClientSideMetrics.class);
         metrics.setEntityId(getEntityId());
         metrics.setTimeBucket(toTimeBucketInHour());
         metrics.setSourceServiceId(getSourceServiceId());
@@ -96,7 +97,7 @@ public class ServiceRelationClientSideMetrics extends Metrics {
 
     @Override
     public Metrics toDay() {
-        ServiceRelationClientSideMetrics metrics = new ServiceRelationClientSideMetrics();
+        ServiceRelationClientSideMetrics metrics = MetricsObjectPool.get(ServiceRelationClientSideMetrics.class);
         metrics.setEntityId(getEntityId());
         metrics.setTimeBucket(toTimeBucketInDay());
         metrics.setSourceServiceId(getSourceServiceId());
@@ -136,11 +137,22 @@ public class ServiceRelationClientSideMetrics extends Metrics {
         return remoteBuilder;
     }
 
+    @Override
+    public void recycle() {
+        this.sourceServiceId = null;
+        this.destServiceId = null;
+        this.componentId = 0;
+        this.entityId = null;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
+
     public static class Builder implements StorageHashMapBuilder<ServiceRelationClientSideMetrics> {
 
         @Override
         public ServiceRelationClientSideMetrics storage2Entity(Map<String, Object> dbMap) {
-            ServiceRelationClientSideMetrics metrics = new ServiceRelationClientSideMetrics();
+            ServiceRelationClientSideMetrics metrics = MetricsObjectPool.get(ServiceRelationClientSideMetrics.class);
             metrics.setSourceServiceId((String) dbMap.get(SOURCE_SERVICE_ID));
             metrics.setDestServiceId((String) dbMap.get(DEST_SERVICE_ID));
             metrics.setComponentId(((Number) dbMap.get(COMPONENT_ID)).intValue());
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceRelationServerSideMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceRelationServerSideMetrics.java
index 5e66b00..748d63c 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceRelationServerSideMetrics.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceRelationServerSideMetrics.java
@@ -24,6 +24,7 @@ import lombok.EqualsAndHashCode;
 import lombok.Getter;
 import lombok.Setter;
 import org.apache.skywalking.oap.server.core.Const;
+import org.apache.skywalking.oap.server.core.MetricsObjectPool;
 import org.apache.skywalking.oap.server.core.analysis.Stream;
 import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics;
 import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor;
@@ -78,7 +79,7 @@ public class ServiceRelationServerSideMetrics extends Metrics {
 
     @Override
     public Metrics toHour() {
-        ServiceRelationServerSideMetrics metrics = new ServiceRelationServerSideMetrics();
+        ServiceRelationServerSideMetrics metrics = MetricsObjectPool.get(ServiceRelationServerSideMetrics.class);
         metrics.setTimeBucket(toTimeBucketInHour());
         metrics.setSourceServiceId(getSourceServiceId());
         metrics.setDestServiceId(getDestServiceId());
@@ -89,7 +90,7 @@ public class ServiceRelationServerSideMetrics extends Metrics {
 
     @Override
     public Metrics toDay() {
-        ServiceRelationServerSideMetrics metrics = new ServiceRelationServerSideMetrics();
+        ServiceRelationServerSideMetrics metrics = MetricsObjectPool.get(ServiceRelationServerSideMetrics.class);
         metrics.setTimeBucket(toTimeBucketInDay());
         metrics.setSourceServiceId(getSourceServiceId());
         metrics.setDestServiceId(getDestServiceId());
@@ -129,11 +130,22 @@ public class ServiceRelationServerSideMetrics extends Metrics {
         return remoteBuilder;
     }
 
+    @Override
+    public void recycle() {
+        this.sourceServiceId = null;
+        this.destServiceId = null;
+        this.componentId = 0;
+        this.entityId = null;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
+
     public static class Builder implements StorageHashMapBuilder<ServiceRelationServerSideMetrics> {
 
         @Override
         public ServiceRelationServerSideMetrics storage2Entity(Map<String, Object> dbMap) {
-            ServiceRelationServerSideMetrics metrics = new ServiceRelationServerSideMetrics();
+            ServiceRelationServerSideMetrics metrics = MetricsObjectPool.get(ServiceRelationServerSideMetrics.class);
             metrics.setEntityId((String) dbMap.get(ENTITY_ID));
             metrics.setSourceServiceId((String) dbMap.get(SOURCE_SERVICE_ID));
             metrics.setDestServiceId((String) dbMap.get(DEST_SERVICE_ID));
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/service/ServiceTraffic.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/service/ServiceTraffic.java
index d5ab808..32fdfc9 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/service/ServiceTraffic.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/service/ServiceTraffic.java
@@ -94,6 +94,16 @@ public class ServiceTraffic extends Metrics {
         return builder;
     }
 
+    @Override
+    public void recycle() {
+        this.name = null;
+        this.nodeType = null;
+        this.group = null;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
+
     public static class Builder implements StorageHashMapBuilder<ServiceTraffic> {
 
         @Override
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/MeterSystem.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/MeterSystem.java
index 9930155..aa2beca 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/MeterSystem.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/MeterSystem.java
@@ -201,7 +201,7 @@ public class MeterSystem implements Service {
 
         CtClass metricsClass = classPool.makeClass(METER_CLASS_PACKAGE + className, parentClass);
 
-        /**
+        /*
          * Create empty construct
          */
         try {
@@ -213,15 +213,15 @@ public class MeterSystem implements Service {
             throw new UnexpectedException(e.getMessage(), e);
         }
 
-        /**
+        /*
          * Generate `AcceptableValue<T> createNew()` method.
          */
         try {
             metricsClass.addMethod(CtNewMethod.make(
                 ""
                     + "public org.apache.skywalking.oap.server.core.analysis.meter.function.AcceptableValue createNew() {"
-                    + "    return new " + METER_CLASS_PACKAGE + className + "();"
-                    + " }"
+                    + "    return org.apache.skywalking.oap.server.core.MetricsObjectPool.get(" + METER_CLASS_PACKAGE + className + ".class);"
+                    + "}"
                 , metricsClass));
         } catch (CannotCompileException e) {
             log.error("Can't generate createNew method for " + className + ".", e);
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/HistogramFunction.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/HistogramFunction.java
index e6ee54e..46b51b7 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/HistogramFunction.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/HistogramFunction.java
@@ -147,6 +147,15 @@ public abstract class HistogramFunction extends Metrics implements AcceptableVal
         return HistogramFunctionBuilder.class;
     }
 
+    @Override
+    public void recycle() {
+        this.entityId = null;
+        this.dataset.recycle();
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
+
     public static class HistogramFunctionBuilder implements StorageHashMapBuilder<HistogramFunction> {
 
         @Override
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/PercentileFunction.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/PercentileFunction.java
index 2b67047..c2fa640 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/PercentileFunction.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/PercentileFunction.java
@@ -42,28 +42,35 @@ import org.apache.skywalking.oap.server.core.storage.StorageHashMapBuilder;
 import org.apache.skywalking.oap.server.core.storage.annotation.Column;
 
 /**
- * PercentileFunction is the implementation of {@link PercentileMetrics} in the meter system. The major difference is
- * the PercentileFunction accepts the {@link PercentileArgument} as input rather than every single request.
+ * PercentileFunction is the implementation of {@link PercentileMetrics} in the meter system. The
+ * major difference is the PercentileFunction accepts the {@link PercentileArgument} as input rather
+ * than every single request.
  */
 @MeterFunction(functionName = "percentile")
 @Slf4j
-public abstract class PercentileFunction extends Metrics implements AcceptableValue<PercentileFunction.PercentileArgument>, MultiIntValuesHolder {
+public abstract class PercentileFunction extends Metrics
+    implements AcceptableValue<PercentileFunction.PercentileArgument>, MultiIntValuesHolder {
     public static final String DATASET = "dataset";
+
     public static final String RANKS = "ranks";
+
     public static final String VALUE = "value";
 
     @Setter
     @Getter
     @Column(columnName = ENTITY_ID, length = 512)
     private String entityId;
+
     @Getter
     @Setter
     @Column(columnName = VALUE, dataType = Column.ValueDataType.LABELED_VALUE, storageOnly = true)
     private DataTable percentileValues = new DataTable(10);
+
     @Getter
     @Setter
     @Column(columnName = DATASET, storageOnly = true)
     private DataTable dataset = new DataTable(30);
+
     /**
      * Rank
      */
@@ -79,20 +86,23 @@ public abstract class PercentileFunction extends Metrics implements AcceptableVa
         if (dataset.size() > 0) {
             if (!value.getBucketedValues().isCompatible(dataset)) {
                 throw new IllegalArgumentException(
-                    "Incompatible BucketedValues [" + value + "] for current PercentileFunction[" + dataset + "]");
+                    "Incompatible BucketedValues [" + value + "] for current PercentileFunction[" +
+                        dataset + "]");
             }
         }
 
         for (final int rank : value.getRanks()) {
             if (rank <= 0) {
-                throw new IllegalArgumentException("Illegal rank value " + rank + ", must be positive");
+                throw new IllegalArgumentException(
+                    "Illegal rank value " + rank + ", must be positive");
             }
         }
 
         if (ranks.size() > 0) {
             if (ranks.size() != value.getRanks().length) {
                 throw new IllegalArgumentException(
-                    "Incompatible ranks size = [" + value.getRanks().length + "] for current PercentileFunction[" + ranks
+                    "Incompatible ranks size = [" + value.getRanks().length +
+                        "] for current PercentileFunction[" + ranks
                         .size() + "]");
             } else {
                 for (final int rank : value.getRanks()) {
@@ -113,7 +123,8 @@ public abstract class PercentileFunction extends Metrics implements AcceptableVa
         final long[] values = value.getBucketedValues().getValues();
         for (int i = 0; i < values.length; i++) {
             final long bucket = value.getBucketedValues().getBuckets()[i];
-            String bucketName = bucket == Long.MIN_VALUE ? Bucket.INFINITE_NEGATIVE : String.valueOf(bucket);
+            String bucketName =
+                bucket == Long.MIN_VALUE ? Bucket.INFINITE_NEGATIVE : String.valueOf(bucket);
             final long bucketValue = values[i];
             dataset.valueAccumulation(bucketName, bucketValue);
         }
@@ -140,7 +151,8 @@ public abstract class PercentileFunction extends Metrics implements AcceptableVa
                 return true;
             } else {
                 if (!this.ranks.equals(ranksOfThat)) {
-                    log.warn("Rank {} doesn't exist in the previous ranks {}", ranksOfThat, this.ranks);
+                    log.warn(
+                        "Rank {} doesn't exist in the previous ranks {}", ranksOfThat, this.ranks);
                     return true;
                 }
             }
@@ -163,7 +175,8 @@ public abstract class PercentileFunction extends Metrics implements AcceptableVa
             }
 
             int count = 0;
-            final List<String> sortedKeys = dataset.sortedKeys(Comparator.comparingInt(Integer::parseInt));
+            final List<String> sortedKeys =
+                dataset.sortedKeys(Comparator.comparingInt(Integer::parseInt));
 
             int loopIndex = 0;
 
@@ -175,7 +188,8 @@ public abstract class PercentileFunction extends Metrics implements AcceptableVa
                     int roof = roofs[rankIdx];
 
                     if (count >= roof) {
-                        percentileValues.put(String.valueOf(ranks.get(rankIdx)), Long.parseLong(key));
+                        percentileValues.put(
+                            String.valueOf(ranks.get(rankIdx)), Long.parseLong(key));
                         loopIndex++;
                     } else {
                         break;
@@ -259,10 +273,12 @@ public abstract class PercentileFunction extends Metrics implements AcceptableVa
     @Getter
     public static class PercentileArgument {
         private final BucketedValues bucketedValues;
+
         private final int[] ranks;
     }
 
-    public static class PercentileFunctionBuilder implements StorageHashMapBuilder<PercentileFunction> {
+    public static class PercentileFunctionBuilder
+        implements StorageHashMapBuilder<PercentileFunction> {
 
         @Override
         public PercentileFunction storage2Entity(final Map<String, Object> dbMap) {
@@ -294,10 +310,12 @@ public abstract class PercentileFunction extends Metrics implements AcceptableVa
 
     @Override
     public boolean equals(Object o) {
-        if (this == o)
+        if (this == o) {
             return true;
-        if (!(o instanceof PercentileFunction))
+        }
+        if (!(o instanceof PercentileFunction)) {
             return false;
+        }
         PercentileFunction function = (PercentileFunction) o;
         return Objects.equals(entityId, function.entityId) &&
             getTimeBucket() == function.getTimeBucket();
@@ -307,4 +325,16 @@ public abstract class PercentileFunction extends Metrics implements AcceptableVa
     public int hashCode() {
         return Objects.hash(entityId, getTimeBucket());
     }
+
+    @Override
+    public void recycle() {
+        this.entityId = null;
+        this.percentileValues.recycle();
+        this.dataset.recycle();
+        this.ranks.recycle();
+        this.isCalculated = false;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/avg/AvgFunction.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/avg/AvgFunction.java
index dc2dec3..86687b3 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/avg/AvgFunction.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/avg/AvgFunction.java
@@ -213,4 +213,16 @@ public abstract class AvgFunction extends Metrics implements AcceptableValue<Lon
     public int hashCode() {
         return Objects.hash(entityId, getTimeBucket());
     }
+
+    @Override
+    public void recycle() {
+        this.entityId = null;
+        this.serviceId = null;
+        this.summation = 0;
+        this.count = 0;
+        this.value = 0;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/avg/AvgHistogramFunction.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/avg/AvgHistogramFunction.java
index f2bfc39..1bf6580 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/avg/AvgHistogramFunction.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/avg/AvgHistogramFunction.java
@@ -221,4 +221,15 @@ public abstract class AvgHistogramFunction extends Metrics implements Acceptable
     public int hashCode() {
         return Objects.hash(entityId, getTimeBucket());
     }
+
+    @Override
+    public void recycle() {
+        this.entityId = null;
+        this.summation.recycle();
+        this.count.recycle();
+        this.dataset.recycle();
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/avg/AvgHistogramPercentileFunction.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/avg/AvgHistogramPercentileFunction.java
index 1dd353f..50b0282 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/avg/AvgHistogramPercentileFunction.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/avg/AvgHistogramPercentileFunction.java
@@ -378,4 +378,18 @@ public abstract class AvgHistogramPercentileFunction extends Metrics implements
     public int hashCode() {
         return Objects.hash(entityId, getTimeBucket());
     }
+
+    @Override
+    public void recycle() {
+        this.entityId = null;
+        this.percentileValues.recycle();
+        this.summation.recycle();
+        this.count.recycle();
+        this.dataset.recycle();
+        this.ranks.recycle();
+        this.isCalculated = false;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/avg/AvgLabeledFunction.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/avg/AvgLabeledFunction.java
index 5e11958..ae88c19 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/avg/AvgLabeledFunction.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/avg/AvgLabeledFunction.java
@@ -217,4 +217,16 @@ public abstract class AvgLabeledFunction extends Metrics implements AcceptableVa
     public int hashCode() {
         return Objects.hash(entityId, getTimeBucket());
     }
+
+    @Override
+    public void recycle() {
+        this.entityId = null;
+        this.serviceId = null;
+        this.summation.recycle();
+        this.count.recycle();
+        this.value.recycle();
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/latest/LatestFunction.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/latest/LatestFunction.java
index 9e49426..5c619c6 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/latest/LatestFunction.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/latest/LatestFunction.java
@@ -41,7 +41,8 @@ import org.apache.skywalking.oap.server.core.storage.annotation.Column;
 
 @MeterFunction(functionName = "latest")
 @ToString
-public abstract class LatestFunction extends Metrics implements AcceptableValue<Long>, LongValueHolder {
+public abstract class LatestFunction extends Metrics
+    implements AcceptableValue<Long>, LongValueHolder {
     protected static final String VALUE = "value";
 
     @Setter
@@ -62,23 +63,27 @@ public abstract class LatestFunction extends Metrics implements AcceptableValue<
     @Column(columnName = VALUE, dataType = Column.ValueDataType.COMMON_VALUE, function = Function.Latest)
     private long value;
 
-    @Override public void accept(MeterEntity entity, Long value) {
+    @Override
+    public void accept(MeterEntity entity, Long value) {
         this.entityId = entity.id();
         this.serviceId = entity.serviceId();
         this.value = value;
     }
 
-    @Entrance public final void combine(@SourceFrom long value) {
+    @Entrance
+    public final void combine(@SourceFrom long value) {
         this.value = value;
     }
 
-    @Override public final boolean combine(Metrics metrics) {
+    @Override
+    public final boolean combine(Metrics metrics) {
         LatestFunction latestFunction = (LatestFunction) metrics;
         combine(latestFunction.value);
         return true;
     }
 
-    @Override public void calculate() {
+    @Override
+    public void calculate() {
 
     }
 
@@ -138,6 +143,16 @@ public abstract class LatestFunction extends Metrics implements AcceptableValue<
         return LatestFunction.LastestStorageBuilder.class;
     }
 
+    @Override
+    public void recycle() {
+        this.entityId = null;
+        this.serviceId = null;
+        this.value = 0;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
+
     public static class LastestStorageBuilder implements StorageHashMapBuilder<LatestFunction> {
         @Override
         public LatestFunction storage2Entity(final Map<String, Object> dbMap) {
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/sum/SumFunction.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/sum/SumFunction.java
index d229f6b..bd712fc 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/sum/SumFunction.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/sum/SumFunction.java
@@ -41,7 +41,8 @@ import org.apache.skywalking.oap.server.core.storage.annotation.Column;
 
 @ToString
 @MeterFunction(functionName = "sum")
-public abstract class SumFunction extends Metrics implements AcceptableValue<Long>, LongValueHolder {
+public abstract class SumFunction extends Metrics
+    implements AcceptableValue<Long>, LongValueHolder {
     protected static final String VALUE = "value";
 
     @Setter
@@ -183,4 +184,14 @@ public abstract class SumFunction extends Metrics implements AcceptableValue<Lon
     public int hashCode() {
         return Objects.hash(getEntityId(), getTimeBucket());
     }
+
+    @Override
+    public void recycle() {
+        this.entityId = null;
+        this.serviceId = null;
+        this.value = 0;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/ApdexMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/ApdexMetrics.java
index 14b4750..ba275b1 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/ApdexMetrics.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/ApdexMetrics.java
@@ -92,7 +92,13 @@ public abstract class ApdexMetrics extends Metrics implements IntValueHolder {
     }
 
     @Override
-    public int getValue() {
-        return value;
+    public void recycle() {
+        this.totalNum = 0;
+        this.sNum = 0;
+        this.tNum = 0;
+        this.value = 0;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
     }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/CPMMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/CPMMetrics.java
index bc0f02f..ae2e90d 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/CPMMetrics.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/CPMMetrics.java
@@ -57,5 +57,14 @@ public abstract class CPMMetrics extends Metrics implements LongValueHolder {
     public void calculate() {
         this.value = total / getDurationInMinute();
     }
+
+    @Override
+    public void recycle() {
+        this.value = 0;
+        this.total = 0;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
 }
 
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/CountMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/CountMetrics.java
index 9a22314..383dbd0 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/CountMetrics.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/CountMetrics.java
@@ -51,4 +51,12 @@ public abstract class CountMetrics extends Metrics implements LongValueHolder {
     @Override
     public void calculate() {
     }
+
+    @Override
+    public void recycle() {
+        this.value = 0;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/DataTable.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/DataTable.java
index 0640d68..3ec0a10 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/DataTable.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/DataTable.java
@@ -17,6 +17,7 @@
 
 package org.apache.skywalking.oap.server.core.analysis.metrics;
 
+import io.netty.util.internal.ObjectPool;
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.HashMap;
@@ -26,6 +27,7 @@ import java.util.stream.Collectors;
 import lombok.EqualsAndHashCode;
 import lombok.ToString;
 import org.apache.skywalking.oap.server.core.Const;
+import org.apache.skywalking.oap.server.core.Recyclable;
 import org.apache.skywalking.oap.server.core.storage.type.StorageDataComplexObject;
 
 /**
@@ -33,8 +35,8 @@ import org.apache.skywalking.oap.server.core.storage.type.StorageDataComplexObje
  */
 @ToString
 @EqualsAndHashCode
-public class DataTable implements StorageDataComplexObject<DataTable> {
-    private HashMap<String, Long> data;
+public class DataTable implements StorageDataComplexObject<DataTable>, Recyclable<DataTable> {
+    private final HashMap<String, Long> data;
 
     public DataTable() {
         data = new HashMap<>();
@@ -153,4 +155,14 @@ public class DataTable implements StorageDataComplexObject<DataTable> {
         });
         return this;
     }
+
+    @Override
+    public void handle(final ObjectPool.Handle<DataTable> handle) {
+        // This is not directly pooled, don't need to handle it
+    }
+
+    @Override
+    public void recycle() {
+        this.data.clear();
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/DoubleAvgMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/DoubleAvgMetrics.java
index 9356c21..15e72a6 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/DoubleAvgMetrics.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/DoubleAvgMetrics.java
@@ -64,4 +64,15 @@ public abstract class DoubleAvgMetrics extends Metrics implements DoubleValueHol
     public final void calculate() {
         this.value = this.summation / this.count;
     }
+
+    @Override
+    public void recycle() {
+        this.summation = 0;
+        this.count = 0;
+        this.value = 0;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+
+        handle.recycle(this);
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/HistogramMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/HistogramMetrics.java
index dbb4870..208ced2 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/HistogramMetrics.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/HistogramMetrics.java
@@ -87,4 +87,12 @@ public abstract class HistogramMetrics extends Metrics {
     @Override
     public final void calculate() {
     }
+
+    @Override
+    public void recycle() {
+        this.dataset.recycle();
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/IntList.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/IntList.java
index b5bd9ef..ce3ee10 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/IntList.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/IntList.java
@@ -18,11 +18,13 @@
 
 package org.apache.skywalking.oap.server.core.analysis.metrics;
 
+import io.netty.util.internal.ObjectPool;
 import java.util.ArrayList;
 import java.util.List;
 import lombok.EqualsAndHashCode;
 import lombok.ToString;
 import org.apache.skywalking.oap.server.core.Const;
+import org.apache.skywalking.oap.server.core.Recyclable;
 import org.apache.skywalking.oap.server.core.storage.type.StorageDataComplexObject;
 
 /**
@@ -30,11 +32,11 @@ import org.apache.skywalking.oap.server.core.storage.type.StorageDataComplexObje
  */
 @ToString
 @EqualsAndHashCode
-public class IntList implements StorageDataComplexObject<IntList> {
+public class IntList implements StorageDataComplexObject<IntList>, Recyclable<IntList> {
     private List<Integer> data;
 
     public IntList(int initialSize) {
-        this.data = new ArrayList(initialSize);
+        this.data = new ArrayList<>(initialSize);
     }
 
     public IntList(String valueString) {
@@ -84,4 +86,14 @@ public class IntList implements StorageDataComplexObject<IntList> {
     public int get(final int idx) {
         return this.data.get(idx);
     }
+
+    @Override
+    public void handle(final ObjectPool.Handle<IntList> handle) {
+        // This is not directly pooled, don't need to handle it
+    }
+
+    @Override
+    public void recycle() {
+        this.data.clear();
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/LongAvgMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/LongAvgMetrics.java
index 661281c..45e6be9 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/LongAvgMetrics.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/LongAvgMetrics.java
@@ -64,4 +64,14 @@ public abstract class LongAvgMetrics extends Metrics implements LongValueHolder
     public final void calculate() {
         this.value = this.summation / this.count;
     }
+
+    @Override
+    public void recycle() {
+        this.summation = 0;
+        this.count = 0;
+        this.value = 0;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/MaxDoubleMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/MaxDoubleMetrics.java
index 5dcef23..0c4d2bc 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/MaxDoubleMetrics.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/MaxDoubleMetrics.java
@@ -52,4 +52,12 @@ public abstract class MaxDoubleMetrics extends Metrics implements DoubleValueHol
     @Override
     public void calculate() {
     }
+
+    @Override
+    public void recycle() {
+        this.value = 0;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/MaxLongMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/MaxLongMetrics.java
index 9b70a47..a7387dc 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/MaxLongMetrics.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/MaxLongMetrics.java
@@ -55,4 +55,12 @@ public abstract class MaxLongMetrics extends Metrics implements LongValueHolder
     @Override
     public void calculate() {
     }
+
+    @Override
+    public void recycle() {
+        this.value = 0;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/Metrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/Metrics.java
index 1bbcd06..b80d5e1 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/Metrics.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/Metrics.java
@@ -18,9 +18,11 @@
 
 package org.apache.skywalking.oap.server.core.analysis.metrics;
 
+import io.netty.util.internal.ObjectPool;
 import lombok.EqualsAndHashCode;
 import lombok.Getter;
 import lombok.Setter;
+import org.apache.skywalking.oap.server.core.Recyclable;
 import org.apache.skywalking.oap.server.core.analysis.TimeBucket;
 import org.apache.skywalking.oap.server.core.remote.data.StreamData;
 import org.apache.skywalking.oap.server.core.storage.StorageData;
@@ -33,7 +35,7 @@ import org.apache.skywalking.oap.server.core.storage.annotation.Column;
 @EqualsAndHashCode(of = {
     "timeBucket"
 })
-public abstract class Metrics extends StreamData implements StorageData {
+public abstract class Metrics extends StreamData implements StorageData, Recyclable<Metrics> {
 
     public static final String TIME_BUCKET = "time_bucket";
     public static final String ENTITY_ID = "entity_id";
@@ -52,6 +54,8 @@ public abstract class Metrics extends StreamData implements StorageData {
     @Getter
     private long lastUpdateTimestamp = 0L;
 
+    protected ObjectPool.Handle<Metrics> handle;
+
     /**
      * Merge the given metrics instance, these two must be the same metrics type.
      *
@@ -153,4 +157,9 @@ public abstract class Metrics extends StreamData implements StorageData {
     }
 
     protected abstract String id0();
+
+    @Override
+    public void handle(final ObjectPool.Handle<Metrics> handle) {
+        this.handle = handle;
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/MinDoubleMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/MinDoubleMetrics.java
index bdc45e6..8cc4300 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/MinDoubleMetrics.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/MinDoubleMetrics.java
@@ -52,4 +52,12 @@ public abstract class MinDoubleMetrics extends Metrics implements DoubleValueHol
     @Override
     public void calculate() {
     }
+
+    @Override
+    public void recycle() {
+        this.value = 0;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/MinLongMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/MinLongMetrics.java
index 88f7fab..9be2984 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/MinLongMetrics.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/MinLongMetrics.java
@@ -52,4 +52,12 @@ public abstract class MinLongMetrics extends Metrics implements LongValueHolder
     @Override
     public void calculate() {
     }
+
+    @Override
+    public void recycle() {
+        this.value = 0;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/PercentMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/PercentMetrics.java
index aa6d32f..85bf20d 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/PercentMetrics.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/PercentMetrics.java
@@ -69,4 +69,14 @@ public abstract class PercentMetrics extends Metrics implements IntValueHolder {
     public int getValue() {
         return percentage;
     }
+
+    @Override
+    public void recycle() {
+        this.total = 0;
+        this.percentage = 0;
+        this.match = 0;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/PercentileMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/PercentileMetrics.java
index 0e1b2a6..e65bb19 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/PercentileMetrics.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/PercentileMetrics.java
@@ -124,4 +124,15 @@ public abstract class PercentileMetrics extends Metrics implements MultiIntValue
                                .flatMapToInt(l -> IntStream.of(l.intValue()))
                                .toArray();
     }
+
+    @Override
+    public void recycle() {
+        this.percentileValues.recycle();
+        this.precision = 0;
+        this.dataset.recycle();
+        this.isCalculated = false;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/PxxMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/PxxMetrics.java
index a65ebce..6c31844 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/PxxMetrics.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/PxxMetrics.java
@@ -106,4 +106,15 @@ public abstract class PxxMetrics extends Metrics implements IntValueHolder {
             }
         }
     }
+
+    @Override
+    public void recycle() {
+        this.value = 0;
+        this.precision = 0;
+        this.isCalculated = false;
+        this.detailGroup.recycle();
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/RateMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/RateMetrics.java
index 830f1d7..839a8d7 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/RateMetrics.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/RateMetrics.java
@@ -73,4 +73,14 @@ public abstract class RateMetrics extends Metrics implements IntValueHolder {
     public int getValue() {
         return percentage;
     }
+
+    @Override
+    public void recycle() {
+        this.denominator = 0;
+        this.percentage = 0;
+        this.numerator = 0;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/SumMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/SumMetrics.java
index a2f3d61..7eae61c 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/SumMetrics.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/SumMetrics.java
@@ -51,4 +51,12 @@ public abstract class SumMetrics extends Metrics implements LongValueHolder {
     @Override
     public void calculate() {
     }
+
+    @Override
+    public void recycle() {
+        this.value = 0;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/worker/ExportWorker.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/worker/ExportWorker.java
index 63090bc..b6f322d 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/worker/ExportWorker.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/worker/ExportWorker.java
@@ -25,8 +25,8 @@ import org.apache.skywalking.oap.server.core.worker.AbstractWorker;
 import org.apache.skywalking.oap.server.library.module.ModuleDefineHolder;
 
 /**
- * A bridge worker. If the {@link ExporterModule} provider declared and provides a implementation of {@link
- * MetricValuesExportService}, forward the export data to it.
+ * A bridge worker. If the {@link ExporterModule} provider declared and provides an implementation
+ * of {@link MetricValuesExportService}, forward the export data to it.
  */
 public class ExportWorker extends AbstractWorker<ExportEvent> {
     private MetricValuesExportService exportService;
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/worker/MetricsAggregateWorker.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/worker/MetricsAggregateWorker.java
index 4e7c59e..5e8a20b 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/worker/MetricsAggregateWorker.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/worker/MetricsAggregateWorker.java
@@ -43,17 +43,17 @@ import org.apache.skywalking.oap.server.telemetry.api.MetricsTag;
 @Slf4j
 public class MetricsAggregateWorker extends AbstractWorker<Metrics> {
     public final long l1FlushPeriod;
-    private AbstractWorker<Metrics> nextWorker;
+    private final AbstractWorker<Metrics> nextWorker;
     private final DataCarrier<Metrics> dataCarrier;
     private final MergableBufferedData<Metrics> mergeDataCache;
-    private CounterMetrics aggregationCounter;
+    private final CounterMetrics aggregationCounter;
     private long lastSendTime = 0;
 
     MetricsAggregateWorker(ModuleDefineHolder moduleDefineHolder, AbstractWorker<Metrics> nextWorker,
                            String modelName, long l1FlushPeriod) {
         super(moduleDefineHolder);
         this.nextWorker = nextWorker;
-        this.mergeDataCache = new MergableBufferedData();
+        this.mergeDataCache = new MergableBufferedData<>();
         String name = "METRICS_L1_AGGREGATION";
         this.dataCarrier = new DataCarrier<>("MetricsAggregateWorker." + modelName, name, 2, 10000);
 
@@ -139,4 +139,4 @@ public class MetricsAggregateWorker extends AbstractWorker<Metrics> {
             flush();
         }
     }
-}
\ No newline at end of file
+}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/worker/MetricsPersistentWorker.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/worker/MetricsPersistentWorker.java
index b216bd0..1f30473 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/worker/MetricsPersistentWorker.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/worker/MetricsPersistentWorker.java
@@ -67,7 +67,7 @@ public class MetricsPersistentWorker extends PersistenceWorker<Metrics> {
     private final boolean enableDatabaseSession;
     private final boolean supportUpdate;
     private long sessionTimeout;
-    private CounterMetrics aggregationCounter;
+    private final CounterMetrics aggregationCounter;
     /**
      * The counter for the round of persistent.
      */
@@ -81,13 +81,13 @@ public class MetricsPersistentWorker extends PersistenceWorker<Metrics> {
     /**
      * @since 8.7.0 TTL settings from {@link org.apache.skywalking.oap.server.core.CoreModuleConfig#getMetricsDataTTL()}
      */
-    private int metricsDataTTL;
+    private final int metricsDataTTL;
 
     MetricsPersistentWorker(ModuleDefineHolder moduleDefineHolder, Model model, IMetricsDAO metricsDAO,
                             AbstractWorker<Metrics> nextAlarmWorker, AbstractWorker<ExportEvent> nextExportWorker,
                             MetricsTransWorker transWorker, boolean enableDatabaseSession, boolean supportUpdate,
                             long storageSessionTimeout, int metricsDataTTL) {
-        super(moduleDefineHolder, new ReadWriteSafeCache<>(new MergableBufferedData(), new MergableBufferedData()));
+        super(moduleDefineHolder, new ReadWriteSafeCache<>(new MergableBufferedData<>(), new MergableBufferedData<>()));
         this.model = model;
         this.context = new HashMap<>(100);
         this.enableDatabaseSession = enableDatabaseSession;
@@ -161,12 +161,12 @@ public class MetricsPersistentWorker extends PersistenceWorker<Metrics> {
     @Override
     public List<PrepareRequest> prepareBatch(Collection<Metrics> lastCollection) {
         if (persistentCounter++ % persistentMod != 0) {
-            return Collections.EMPTY_LIST;
+            return Collections.emptyList();
         }
 
         long start = System.currentTimeMillis();
         if (lastCollection.size() == 0) {
-            return Collections.EMPTY_LIST;
+            return Collections.emptyList();
         }
 
         /*
@@ -233,11 +233,20 @@ public class MetricsPersistentWorker extends PersistenceWorker<Metrics> {
                     metrics.setLastUpdateTimestamp(timestamp);
                 }
 
-                /*
-                 * The `metrics` should be not changed in all above process. Exporter is an async process.
-                 */
-                nextExportWorker.ifPresent(exportEvenWorker -> exportEvenWorker.in(
-                    new ExportEvent(metrics, ExportEvent.EventType.INCREMENT)));
+                if (nextExportWorker.isPresent()) {
+                    /*
+                     * The `metrics` should be not changed in all above process as exporter is an
+                     * async process.
+                     *
+                     * Exporter is also responsible to recycle the passed-in metrics.
+                     */
+                    nextExportWorker.get().in(new ExportEvent(metrics, ExportEvent.EventType.INCREMENT));
+                } else {
+                    /*
+                     * No exporter is configured, metrics can be recycled right now.
+                     */
+                    metrics.recycle();
+                }
             }
         } catch (Throwable t) {
             log.error(t.getMessage(), t);
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/worker/MetricsStreamProcessor.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/worker/MetricsStreamProcessor.java
index 1fb1d41..d4691d9 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/worker/MetricsStreamProcessor.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/worker/MetricsStreamProcessor.java
@@ -119,7 +119,6 @@ public class MetricsStreamProcessor implements StreamProcessor<Metrics> {
         this.create(moduleDefineHolder, StreamDefinition.from(stream), metricsClass);
     }
 
-    @SuppressWarnings("unchecked")
     public void create(ModuleDefineHolder moduleDefineHolder,
                        StreamDefinition stream,
                        Class<? extends Metrics> metricsClass) throws StorageException {
@@ -148,7 +147,7 @@ public class MetricsStreamProcessor implements StreamProcessor<Metrics> {
         MetricsTransWorker transWorker = null;
 
         final MetricsExtension metricsExtension = metricsClass.getAnnotation(MetricsExtension.class);
-        /**
+        /*
          * All metrics default are `supportDownSampling` and `insertAndUpdate`, unless it has explicit definition.
          */
         boolean supportDownSampling = true;
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/exporter/ExportEvent.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/exporter/ExportEvent.java
index 8a38efc..524ed7a 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/exporter/ExportEvent.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/exporter/ExportEvent.java
@@ -19,6 +19,7 @@
 package org.apache.skywalking.oap.server.core.exporter;
 
 import lombok.Getter;
+import lombok.RequiredArgsConstructor;
 import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics;
 
 /**
@@ -26,17 +27,13 @@ import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics;
  * changed in any case.
  */
 @Getter
+@RequiredArgsConstructor
 public class ExportEvent {
     /**
      * Fields of this should not be changed in any case.
      */
-    private Metrics metrics;
-    private EventType type;
-
-    public ExportEvent(Metrics metrics, EventType type) {
-        this.metrics = metrics;
-        this.type = type;
-    }
+    private final Metrics metrics;
+    private final EventType type;
 
     public enum EventType {
         /**
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/remote/client/GRPCRemoteClient.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/remote/client/GRPCRemoteClient.java
index 51fda20..b2e90ae 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/remote/client/GRPCRemoteClient.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/remote/client/GRPCRemoteClient.java
@@ -28,6 +28,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.skywalking.apm.commons.datacarrier.DataCarrier;
 import org.apache.skywalking.apm.commons.datacarrier.consumer.IConsumer;
+import org.apache.skywalking.oap.server.core.Recyclable;
 import org.apache.skywalking.oap.server.core.remote.data.StreamData;
 import org.apache.skywalking.oap.server.core.remote.grpc.proto.Empty;
 import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteMessage;
@@ -149,6 +150,10 @@ public class GRPCRemoteClient implements RemoteClient {
         builder.setRemoteData(streamData.serialize());
 
         this.getDataCarrier().produce(builder.build());
+
+        if (streamData instanceof Recyclable) {
+            ((Recyclable<?>) streamData).recycle();
+        }
     }
 
     class RemoteMessageConsumer implements IConsumer<RemoteMessage> {
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Event.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Event.java
index f985d08..7d8a14e 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Event.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/Event.java
@@ -230,6 +230,24 @@ public class Event extends Metrics implements ISource, WithMetadata, LongValueHo
         return id;
     }
 
+    @Override
+    public void recycle() {
+        this.uuid = null;
+        this.service = null;
+        this.serviceInstance = null;
+        this.endpoint = null;
+        this.name = null;
+        this.type = null;
+        this.message = null;
+        this.parameters = null;
+        this.startTime = 0;
+        this.endTime = 0;
+        this.value = 0;
+        setTimeBucket(0);
+        setLastUpdateTimestamp(0);
+        handle.recycle(this);
+    }
+
     public static class Builder implements StorageHashMapBuilder<Event> {
         @Override
         public Map<String, Object> entity2Storage(Event storageData) {
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/endpoint/EndpointCallRelationTest.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/endpoint/EndpointCallRelationTest.java
index c509604..f9846ef 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/endpoint/EndpointCallRelationTest.java
+++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/endpoint/EndpointCallRelationTest.java
@@ -18,18 +18,21 @@
 
 package org.apache.skywalking.oap.server.core.analysis.manual.relation.endpoint;
 
+import org.apache.skywalking.oap.server.core.MetricsObjectPool;
 import org.junit.Assert;
 import org.junit.Test;
 
 public class EndpointCallRelationTest {
     @Test
     public void testEndpointRelationServerSideMetricsEquals() {
-        EndpointRelationServerSideMetrics thisObject = new EndpointRelationServerSideMetrics();
+        EndpointRelationServerSideMetrics thisObject =
+            MetricsObjectPool.get(EndpointRelationServerSideMetrics.class);
         thisObject.setEntityId(
             "VXNlcg==.0-VXNlcg==-em1iaXotcHJvbW90aW9uMi1hZG1pbkAxMjUyNw==.1-L0Bpbi9hcGkvaGVhbHRo");
         thisObject.setTimeBucket(202101071505L);
 
-        EndpointRelationServerSideMetrics otherObject = new EndpointRelationServerSideMetrics();
+        EndpointRelationServerSideMetrics otherObject =
+            MetricsObjectPool.get(EndpointRelationServerSideMetrics.class);
         otherObject.setEntityId(
             "VXNlcg==.0-VXNlcg==-em1iaXotcHJvbW90aW9uMi1hZG1pbkAxMjUyNw==.1-L0Bpbi9hcGkvaGVhbHRo");
         otherObject.setTimeBucket(202101071505L);
@@ -39,12 +42,14 @@ public class EndpointCallRelationTest {
 
     @Test
     public void testEndpointRelationServerSideMetricsNotEquals() {
-        EndpointRelationServerSideMetrics thisObject = new EndpointRelationServerSideMetrics();
+        EndpointRelationServerSideMetrics thisObject =
+            MetricsObjectPool.get(EndpointRelationServerSideMetrics.class);
         thisObject.setEntityId(
             "VXNlcg==.0-VXNlcg==-em1iaXotcHJvbW90aW9uMi1hZG1pbkAxMjUyNw==.1-L0Bpbi9hcGkvaGVhbHRo");
         thisObject.setTimeBucket(202101071505L);
 
-        EndpointRelationServerSideMetrics otherObject = new EndpointRelationServerSideMetrics();
+        EndpointRelationServerSideMetrics otherObject =
+            MetricsObjectPool.get(EndpointRelationServerSideMetrics.class);
         otherObject.setEntityId(
             "VXNlcg==.0-VXNlcg==-em1iaXotcHJvbW90aW9uMi1hZG1pbkAxMjUyNw==.1-L0Bpbi9hcGkvaGVhbHRo");
         otherObject.setTimeBucket(202101071506L);
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/instance/ServiceInstanceRelationTest.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/instance/ServiceInstanceRelationTest.java
index 18dc008..5d3b696 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/instance/ServiceInstanceRelationTest.java
+++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/instance/ServiceInstanceRelationTest.java
@@ -18,18 +18,21 @@
 
 package org.apache.skywalking.oap.server.core.analysis.manual.relation.instance;
 
+import org.apache.skywalking.oap.server.core.MetricsObjectPool;
 import org.junit.Assert;
 import org.junit.Test;
 
 public class ServiceInstanceRelationTest {
     @Test
     public void testServiceInstanceRelationClientSideMetricsEquals() {
-        ServiceInstanceRelationClientSideMetrics thisObject = new ServiceInstanceRelationClientSideMetrics();
+        ServiceInstanceRelationClientSideMetrics thisObject =
+            MetricsObjectPool.get(ServiceInstanceRelationClientSideMetrics.class);
         thisObject.setEntityId(
             "em1jLWJlYWNvbi1taWRkbGV3YXJlQDExMTIz.1_MTAuMTExLjIzMi4yMDc=-MTkyLjE2OC40Ni4xNDM6NDY2MDY=.0_MTkyLjE2OC40Ni4xNDM6NDY2MDY=");
         thisObject.setTimeBucket(202101071505L);
 
-        ServiceInstanceRelationClientSideMetrics otherObject = new ServiceInstanceRelationClientSideMetrics();
+        ServiceInstanceRelationClientSideMetrics otherObject =
+            MetricsObjectPool.get(ServiceInstanceRelationClientSideMetrics.class);
         otherObject.setEntityId(
             "em1jLWJlYWNvbi1taWRkbGV3YXJlQDExMTIz.1_MTAuMTExLjIzMi4yMDc=-MTkyLjE2OC40Ni4xNDM6NDY2MDY=.0_MTkyLjE2OC40Ni4xNDM6NDY2MDY=");
         otherObject.setTimeBucket(202101071505L);
@@ -39,12 +42,14 @@ public class ServiceInstanceRelationTest {
 
     @Test
     public void testServiceInstanceRelationClientSideMetricsNotEquals() {
-        ServiceInstanceRelationClientSideMetrics thisObject = new ServiceInstanceRelationClientSideMetrics();
+        ServiceInstanceRelationClientSideMetrics thisObject =
+            MetricsObjectPool.get(ServiceInstanceRelationClientSideMetrics.class);
         thisObject.setEntityId(
             "em1jLWJlYWNvbi1taWRkbGV3YXJlQDExMTIz.1_MTAuMTExLjIzMi4yMDc=-MTkyLjE2OC40Ni4xNDM6NDY2MDY=.0_MTkyLjE2OC40Ni4xNDM6NDY2MDY=");
         thisObject.setTimeBucket(202101071505L);
 
-        ServiceInstanceRelationClientSideMetrics otherObject = new ServiceInstanceRelationClientSideMetrics();
+        ServiceInstanceRelationClientSideMetrics otherObject =
+            MetricsObjectPool.get(ServiceInstanceRelationClientSideMetrics.class);
         otherObject.setEntityId(
             "em1jLWJlYWNvbi1taWRkbGV3YXJlQDExMTIz.1_MTAuMTExLjIzMi4yMDc=-MTkyLjE2OC40Ni4xNDM6NDY2MDY=.0_MTkyLjE2OC40Ni4xNDM6NDY2MDY=");
         otherObject.setTimeBucket(202101071506L);
@@ -54,12 +59,14 @@ public class ServiceInstanceRelationTest {
 
     @Test
     public void testServiceInstanceRelationServerSideMetricsEquals() {
-        ServiceInstanceRelationServerSideMetrics thisObject = new ServiceInstanceRelationServerSideMetrics();
+        ServiceInstanceRelationServerSideMetrics thisObject =
+            MetricsObjectPool.get(ServiceInstanceRelationServerSideMetrics.class);
         thisObject.setEntityId(
             "em1jLWJlYWNvbi1taWRkbGV3YXJlQDExMTIz.1_MTAuMTExLjIzMi4yMDc=-MTkyLjE2OC40Ni4xNDM6NDY2MDY=.0_MTkyLjE2OC40Ni4xNDM6NDY2MDY=");
         thisObject.setTimeBucket(202101071505L);
 
-        ServiceInstanceRelationServerSideMetrics otherObject = new ServiceInstanceRelationServerSideMetrics();
+        ServiceInstanceRelationServerSideMetrics otherObject =
+            MetricsObjectPool.get(ServiceInstanceRelationServerSideMetrics.class);
         otherObject.setEntityId(
             "em1jLWJlYWNvbi1taWRkbGV3YXJlQDExMTIz.1_MTAuMTExLjIzMi4yMDc=-MTkyLjE2OC40Ni4xNDM6NDY2MDY=.0_MTkyLjE2OC40Ni4xNDM6NDY2MDY=");
         otherObject.setTimeBucket(202101071505L);
@@ -69,12 +76,14 @@ public class ServiceInstanceRelationTest {
 
     @Test
     public void testServiceInstanceRelationServerSideMetricsNotEquals() {
-        ServiceInstanceRelationServerSideMetrics thisObject = new ServiceInstanceRelationServerSideMetrics();
+        ServiceInstanceRelationServerSideMetrics thisObject =
+            MetricsObjectPool.get(ServiceInstanceRelationServerSideMetrics.class);
         thisObject.setEntityId(
             "em1jLWJlYWNvbi1taWRkbGV3YXJlQDExMTIz.1_MTAuMTExLjIzMi4yMDc=-MTkyLjE2OC40Ni4xNDM6NDY2MDY=.0_MTkyLjE2OC40Ni4xNDM6NDY2MDY=");
         thisObject.setTimeBucket(202101071505L);
 
-        ServiceInstanceRelationServerSideMetrics otherObject = new ServiceInstanceRelationServerSideMetrics();
+        ServiceInstanceRelationServerSideMetrics otherObject =
+            MetricsObjectPool.get(ServiceInstanceRelationServerSideMetrics.class);
         otherObject.setEntityId(
             "em1jLWJlYWNvbi1taWRkbGV3YXJlQDExMTIz.1_MTAuMTExLjIzMi4yMDc=-MTkyLjE2OC40Ni4xNDM6NDY2MDY=.0_MTkyLjE2OC40Ni4xNDM6NDY2MDY=");
         otherObject.setTimeBucket(202101071506L);
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceRelationTest.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceRelationTest.java
index 6bf8282..002250d 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceRelationTest.java
+++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/manual/relation/service/ServiceRelationTest.java
@@ -18,17 +18,20 @@
 
 package org.apache.skywalking.oap.server.core.analysis.manual.relation.service;
 
+import org.apache.skywalking.oap.server.core.MetricsObjectPool;
 import org.junit.Assert;
 import org.junit.Test;
 
 public class ServiceRelationTest {
     @Test
     public void testServiceRelationClientSideMetricsEquals() {
-        ServiceRelationClientSideMetrics thisObject = new ServiceRelationClientSideMetrics();
+        ServiceRelationClientSideMetrics thisObject =
+            MetricsObjectPool.get(ServiceRelationClientSideMetrics.class);
         thisObject.setEntityId("VXNlcg==.0-em0tY2xpZW50LXNldHRpbmctd2ViYXBpQDEwNjQ4.1");
         thisObject.setTimeBucket(202101071505L);
 
-        ServiceRelationClientSideMetrics otherObject = new ServiceRelationClientSideMetrics();
+        ServiceRelationClientSideMetrics otherObject =
+            MetricsObjectPool.get(ServiceRelationClientSideMetrics.class);
         otherObject.setEntityId("VXNlcg==.0-em0tY2xpZW50LXNldHRpbmctd2ViYXBpQDEwNjQ4.1");
         otherObject.setTimeBucket(202101071505L);
 
@@ -37,11 +40,13 @@ public class ServiceRelationTest {
 
     @Test
     public void testServiceRelationClientSideMetricsNotEquals() {
-        ServiceRelationClientSideMetrics thisObject = new ServiceRelationClientSideMetrics();
+        ServiceRelationClientSideMetrics thisObject =
+            MetricsObjectPool.get(ServiceRelationClientSideMetrics.class);
         thisObject.setEntityId("VXNlcg==.0-em0tY2xpZW50LXNldHRpbmctd2ViYXBpQDEwNjQ4.1");
         thisObject.setTimeBucket(202101071505L);
 
-        ServiceRelationClientSideMetrics otherObject = new ServiceRelationClientSideMetrics();
+        ServiceRelationClientSideMetrics otherObject =
+            MetricsObjectPool.get(ServiceRelationClientSideMetrics.class);
         otherObject.setEntityId("VXNlcg==.0-em0tY2xpZW50LXNldHRpbmctd2ViYXBpQDEwNjQ4.1");
         otherObject.setTimeBucket(202101071506L);
 
@@ -50,11 +55,13 @@ public class ServiceRelationTest {
 
     @Test
     public void testServiceRelationServerSideMetricsEquals() {
-        ServiceRelationServerSideMetrics thisObject = new ServiceRelationServerSideMetrics();
+        ServiceRelationServerSideMetrics thisObject =
+            MetricsObjectPool.get(ServiceRelationServerSideMetrics.class);
         thisObject.setEntityId("VXNlcg==.0-em0tY2xpZW50LXNldHRpbmctd2ViYXBpQDEwNjQ4.1");
         thisObject.setTimeBucket(202101071505L);
 
-        ServiceRelationServerSideMetrics otherObject = new ServiceRelationServerSideMetrics();
+        ServiceRelationServerSideMetrics otherObject =
+            MetricsObjectPool.get(ServiceRelationServerSideMetrics.class);
         otherObject.setEntityId("VXNlcg==.0-em0tY2xpZW50LXNldHRpbmctd2ViYXBpQDEwNjQ4.1");
         otherObject.setTimeBucket(202101071505L);
 
@@ -63,11 +70,13 @@ public class ServiceRelationTest {
 
     @Test
     public void testServiceRelationServerSideMetricsNotEquals() {
-        ServiceRelationServerSideMetrics thisObject = new ServiceRelationServerSideMetrics();
+        ServiceRelationServerSideMetrics thisObject =
+            MetricsObjectPool.get(ServiceRelationServerSideMetrics.class);
         thisObject.setEntityId("VXNlcg==.0-em0tY2xpZW50LXNldHRpbmctd2ViYXBpQDEwNjQ4.1");
         thisObject.setTimeBucket(202101071505L);
 
-        ServiceRelationServerSideMetrics otherObject = new ServiceRelationServerSideMetrics();
+        ServiceRelationServerSideMetrics otherObject =
+            MetricsObjectPool.get(ServiceRelationServerSideMetrics.class);
         otherObject.setEntityId("VXNlcg==.0-em0tY2xpZW50LXNldHRpbmctd2ViYXBpQDEwNjQ4.1");
         otherObject.setTimeBucket(202101071506L);
 
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/meter/function/HistogramFunctionTest.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/meter/function/HistogramFunctionTest.java
index 5ddbb0a..9804a4a 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/meter/function/HistogramFunctionTest.java
+++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/meter/function/HistogramFunctionTest.java
@@ -20,6 +20,7 @@ package org.apache.skywalking.oap.server.core.analysis.meter.function;
 
 import java.util.Map;
 import java.util.stream.IntStream;
+import org.apache.skywalking.oap.server.core.MetricsObjectPool;
 import org.apache.skywalking.oap.server.core.analysis.meter.MeterEntity;
 import org.apache.skywalking.oap.server.core.analysis.metrics.DataTable;
 import org.apache.skywalking.oap.server.core.query.type.Bucket;
@@ -54,7 +55,7 @@ public class HistogramFunctionTest {
 
     @Test
     public void testFunction() {
-        HistogramFunctionInst inst = new HistogramFunctionInst();
+        HistogramFunctionInst inst = MetricsObjectPool.get(HistogramFunctionInst.class);
         inst.accept(
             MeterEntity.newService("service-test"),
             new BucketedValues(
@@ -90,7 +91,7 @@ public class HistogramFunctionTest {
 
     @Test
     public void testFunctionWithInfinite() {
-        HistogramFunctionInst inst = new HistogramFunctionInst();
+        HistogramFunctionInst inst = MetricsObjectPool.get(HistogramFunctionInst.class);
         inst.accept(
             MeterEntity.newService("service-test"),
             new BucketedValues(
@@ -118,7 +119,7 @@ public class HistogramFunctionTest {
 
     @Test(expected = IllegalArgumentException.class)
     public void testIncompatible() {
-        HistogramFunctionInst inst = new HistogramFunctionInst();
+        HistogramFunctionInst inst = MetricsObjectPool.get(HistogramFunctionInst.class);
         inst.accept(
             MeterEntity.newService("service-test"),
             new BucketedValues(
@@ -144,7 +145,7 @@ public class HistogramFunctionTest {
 
     @Test
     public void testSerialization() {
-        HistogramFunctionInst inst = new HistogramFunctionInst();
+        HistogramFunctionInst inst = MetricsObjectPool.get(HistogramFunctionInst.class);
         inst.accept(
             MeterEntity.newService("service-test"),
             new BucketedValues(
@@ -156,7 +157,7 @@ public class HistogramFunctionTest {
             })
         );
 
-        final HistogramFunctionInst inst2 = new HistogramFunctionInst();
+        final HistogramFunctionInst inst2 = MetricsObjectPool.get(HistogramFunctionInst.class);
         inst2.deserialize(inst.serialize().build());
 
         Assert.assertEquals(inst, inst2);
@@ -166,7 +167,7 @@ public class HistogramFunctionTest {
 
     @Test
     public void testSerializationInInfinite() {
-        HistogramFunctionInst inst = new HistogramFunctionInst();
+        HistogramFunctionInst inst = MetricsObjectPool.get(HistogramFunctionInst.class);
         inst.accept(
             MeterEntity.newService("service-test"),
             new BucketedValues(
@@ -178,7 +179,7 @@ public class HistogramFunctionTest {
             })
         );
 
-        final HistogramFunctionInst inst2 = new HistogramFunctionInst();
+        final HistogramFunctionInst inst2 = MetricsObjectPool.get(HistogramFunctionInst.class);
         inst2.deserialize(inst.serialize().build());
 
         Assert.assertEquals(inst, inst2);
@@ -188,7 +189,7 @@ public class HistogramFunctionTest {
 
     @Test
     public void testBuilder() throws IllegalAccessException, InstantiationException {
-        HistogramFunctionInst inst = new HistogramFunctionInst();
+        HistogramFunctionInst inst = MetricsObjectPool.get(HistogramFunctionInst.class);
         inst.accept(
             MeterEntity.newService("service-test"),
             new BucketedValues(
@@ -212,11 +213,11 @@ public class HistogramFunctionTest {
         Assert.assertEquals(inst.getDataset(), inst2.getDataset());
     }
 
-    private static class HistogramFunctionInst extends HistogramFunction {
+    public static class HistogramFunctionInst extends HistogramFunction {
 
         @Override
         public AcceptableValue<BucketedValues> createNew() {
-            return new HistogramFunctionInst();
+            return MetricsObjectPool.get(HistogramFunctionInst.class);
         }
     }
 }
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/meter/function/avg/AvgHistogramFunctionTest.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/meter/function/avg/AvgHistogramFunctionTest.java
index b5d0588..b9a2800 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/meter/function/avg/AvgHistogramFunctionTest.java
+++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/meter/function/avg/AvgHistogramFunctionTest.java
@@ -20,6 +20,7 @@ package org.apache.skywalking.oap.server.core.analysis.meter.function.avg;
 
 import java.util.Map;
 import java.util.stream.IntStream;
+import org.apache.skywalking.oap.server.core.MetricsObjectPool;
 import org.apache.skywalking.oap.server.core.analysis.meter.MeterEntity;
 import org.apache.skywalking.oap.server.core.analysis.meter.function.AcceptableValue;
 import org.apache.skywalking.oap.server.core.analysis.meter.function.BucketedValues;
@@ -51,7 +52,7 @@ public class AvgHistogramFunctionTest {
 
     @Test
     public void testFunction() {
-        HistogramFunctionInst inst = new HistogramFunctionInst();
+        HistogramFunctionInst inst = MetricsObjectPool.get(HistogramFunctionInst.class);
         inst.accept(
             MeterEntity.newService("service-test"),
             new BucketedValues(
@@ -88,7 +89,7 @@ public class AvgHistogramFunctionTest {
 
     @Test
     public void testFunctionWithInfinite() {
-        HistogramFunctionInst inst = new HistogramFunctionInst();
+        HistogramFunctionInst inst = MetricsObjectPool.get(HistogramFunctionInst.class);
         inst.accept(
             MeterEntity.newService("service-test"),
             new BucketedValues(
@@ -118,7 +119,7 @@ public class AvgHistogramFunctionTest {
 
     @Test
     public void testSerialization() {
-        HistogramFunctionInst inst = new HistogramFunctionInst();
+        HistogramFunctionInst inst = MetricsObjectPool.get(HistogramFunctionInst.class);
         inst.accept(
             MeterEntity.newService("service-test"),
             new BucketedValues(
@@ -131,7 +132,7 @@ public class AvgHistogramFunctionTest {
         );
         inst.calculate();
 
-        final HistogramFunctionInst inst2 = new HistogramFunctionInst();
+        final HistogramFunctionInst inst2 = MetricsObjectPool.get(HistogramFunctionInst.class);
         inst2.deserialize(inst.serialize().build());
 
         Assert.assertEquals(inst, inst2);
@@ -141,7 +142,7 @@ public class AvgHistogramFunctionTest {
 
     @Test
     public void testSerializationInInfinite() {
-        HistogramFunctionInst inst = new HistogramFunctionInst();
+        HistogramFunctionInst inst = MetricsObjectPool.get(HistogramFunctionInst.class);
         inst.accept(
             MeterEntity.newService("service-test"),
             new BucketedValues(
@@ -153,7 +154,7 @@ public class AvgHistogramFunctionTest {
             })
         );
 
-        final HistogramFunctionInst inst2 = new HistogramFunctionInst();
+        final HistogramFunctionInst inst2 = MetricsObjectPool.get(HistogramFunctionInst.class);
         inst2.deserialize(inst.serialize().build());
 
         Assert.assertEquals(inst, inst2);
@@ -163,7 +164,7 @@ public class AvgHistogramFunctionTest {
 
     @Test
     public void testBuilder() throws IllegalAccessException, InstantiationException {
-        HistogramFunctionInst inst = new HistogramFunctionInst();
+        HistogramFunctionInst inst = MetricsObjectPool.get(HistogramFunctionInst.class);
         inst.accept(
             MeterEntity.newService("service-test"),
             new BucketedValues(
@@ -193,7 +194,7 @@ public class AvgHistogramFunctionTest {
     @Test
     public void testGroup() {
 
-        HistogramFunctionInst inst = new HistogramFunctionInst();
+        HistogramFunctionInst inst = MetricsObjectPool.get(HistogramFunctionInst.class);
         BucketedValues bv1 = new BucketedValues(
             BUCKETS, new long[] {
             0,
@@ -244,11 +245,11 @@ public class AvgHistogramFunctionTest {
         }, results);
     }
 
-    private static class HistogramFunctionInst extends AvgHistogramFunction {
+    public static class HistogramFunctionInst extends AvgHistogramFunction {
 
         @Override
         public AcceptableValue<BucketedValues> createNew() {
-            return new HistogramFunctionInst();
+            return MetricsObjectPool.get(HistogramFunctionInst.class);
         }
     }
 }
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/LongAvgMetricsTest.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/LongAvgMetricsTest.java
index 4867dc5..9e848d6 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/LongAvgMetricsTest.java
+++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/LongAvgMetricsTest.java
@@ -18,6 +18,7 @@
 
 package org.apache.skywalking.oap.server.core.analysis.metrics;
 
+import org.apache.skywalking.oap.server.core.MetricsObjectPool;
 import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData;
 import org.junit.Assert;
 import org.junit.Test;
@@ -25,7 +26,7 @@ import org.junit.Test;
 public class LongAvgMetricsTest {
     @Test
     public void testEntranceCombine() {
-        LongAvgMetricsImpl impl = new LongAvgMetricsImpl();
+        LongAvgMetricsImpl impl = MetricsObjectPool.get(LongAvgMetricsImpl.class);
         impl.combine(12, 1);
         impl.combine(24, 2);
         impl.combine(36, 3);
@@ -35,11 +36,11 @@ public class LongAvgMetricsTest {
 
     @Test
     public void testSelfCombine() {
-        LongAvgMetricsImpl impl = new LongAvgMetricsImpl();
+        LongAvgMetricsImpl impl = MetricsObjectPool.get(LongAvgMetricsImpl.class);
         impl.combine(12, 1);
         impl.combine(24, 2);
 
-        LongAvgMetricsImpl impl2 = new LongAvgMetricsImpl();
+        LongAvgMetricsImpl impl2 = MetricsObjectPool.get(LongAvgMetricsImpl.class);
         impl2.combine(24, 1);
         impl2.combine(48, 2);
 
@@ -49,7 +50,7 @@ public class LongAvgMetricsTest {
         Assert.assertEquals(18, impl.getValue());
     }
 
-    public class LongAvgMetricsImpl extends LongAvgMetrics {
+    public static class LongAvgMetricsImpl extends LongAvgMetrics {
 
         @Override
         protected String id0() {
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/MaxLongMetricsTest.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/MaxLongMetricsTest.java
index f3dcd24..0c7be6e 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/MaxLongMetricsTest.java
+++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/MaxLongMetricsTest.java
@@ -18,6 +18,7 @@
 
 package org.apache.skywalking.oap.server.core.analysis.metrics;
 
+import org.apache.skywalking.oap.server.core.MetricsObjectPool;
 import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData;
 import org.junit.Assert;
 import org.junit.Test;
@@ -29,7 +30,7 @@ public class MaxLongMetricsTest {
 
     @Test
     public void testEntranceCombine() {
-        MaxLongMetricsImpl impl = new MaxLongMetricsImpl();
+        MaxLongMetricsImpl impl = MetricsObjectPool.get(MaxLongMetricsImpl.class);
         impl.combine(10);
         impl.combine(5);
         impl.combine(20);
@@ -39,11 +40,11 @@ public class MaxLongMetricsTest {
 
     @Test
     public void testSelfCombine() {
-        MaxLongMetricsImpl impl = new MaxLongMetricsImpl();
+        MaxLongMetricsImpl impl = MetricsObjectPool.get(MaxLongMetricsImpl.class);
         impl.combine(10);
         impl.combine(5);
 
-        MaxLongMetricsImpl impl2 = new MaxLongMetricsImpl();
+        MaxLongMetricsImpl impl2 = MetricsObjectPool.get(MaxLongMetricsImpl.class);
         impl2.combine(2);
         impl2.combine(6);
 
@@ -51,7 +52,7 @@ public class MaxLongMetricsTest {
         Assert.assertEquals(10, impl.getValue());
     }
 
-    public class MaxLongMetricsImpl extends MaxLongMetrics {
+    public static class MaxLongMetricsImpl extends MaxLongMetrics {
 
         @Override
         protected String id0() {
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/MetricsTest.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/MetricsTest.java
index 351441e..2b9dcfd 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/MetricsTest.java
+++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/MetricsTest.java
@@ -18,6 +18,7 @@
 
 package org.apache.skywalking.oap.server.core.analysis.metrics;
 
+import org.apache.skywalking.oap.server.core.MetricsObjectPool;
 import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData;
 import org.junit.Assert;
 import org.junit.Test;
@@ -25,13 +26,13 @@ import org.junit.Test;
 public class MetricsTest {
     @Test
     public void testTransferToTimeBucket() {
-        MetricsMocker mocker = new MetricsMocker();
+        MetricsMocker mocker = MetricsObjectPool.get(MetricsMocker.class);
 
         mocker.setTimeBucket(201809120511L);
         Assert.assertEquals(2018091205L, mocker.toTimeBucketInHour());
         Assert.assertEquals(20180912L, mocker.toTimeBucketInDay());
 
-        mocker = new MetricsMocker();
+        mocker = MetricsObjectPool.get(MetricsMocker.class);
 
         mocker.setTimeBucket(2018091205L);
         Assert.assertEquals(20180912L, mocker.toTimeBucketInDay());
@@ -39,7 +40,7 @@ public class MetricsTest {
 
     @Test
     public void testIllegalTransferToTimeBucket() {
-        MetricsMocker mocker = new MetricsMocker();
+        MetricsMocker mocker = MetricsObjectPool.get(MetricsMocker.class);
         mocker.setTimeBucket(2018091205L);
 
         boolean status = true;
@@ -50,7 +51,7 @@ public class MetricsTest {
         }
         Assert.assertFalse(status);
 
-        mocker = new MetricsMocker();
+        mocker = MetricsObjectPool.get(MetricsMocker.class);
         mocker.setTimeBucket(20180912L);
 
         status = true;
@@ -70,7 +71,7 @@ public class MetricsTest {
         Assert.assertFalse(status);
     }
 
-    public class MetricsMocker extends Metrics {
+    public static class MetricsMocker extends Metrics {
 
         @Override
         protected String id0() {
@@ -111,5 +112,10 @@ public class MetricsTest {
         public int remoteHashCode() {
             return 0;
         }
+
+        @Override
+        public void recycle() {
+            handle.recycle(this);
+        }
     }
 }