You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2020/02/01 16:00:22 UTC
[skywalking] branch master updated: Performance tuning,
replace AtomicInteger with AtomicIntegerFieldUpdater (#4305)
This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking.git
The following commit(s) were added to refs/heads/master by this push:
new 360eae2 Performance tuning, replace AtomicInteger with AtomicIntegerFieldUpdater (#4305)
360eae2 is described below
commit 360eae22a67219a2c026a2130cf0540ac1f04a01
Author: kezhenxu94 <ke...@apache.org>
AuthorDate: Sun Feb 2 00:00:14 2020 +0800
Performance tuning, replace AtomicInteger with AtomicIntegerFieldUpdater (#4305)
Motivation:
Reduce unnecessary memory allocation in frequently used class.
Modifications:
Replace the `AtomicInteger` with `AtomicIntegerFieldUpdater`
Result:
We can save 4 bytes (for the reference to `AtomicInteger` itself) for each `TracingContext`, which saves credible memory in a high-concurrent agent service.
---
.../apm/agent/core/context/TracingContext.java | 78 ++++++++--------------
1 file changed, 29 insertions(+), 49 deletions(-)
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/TracingContext.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/TracingContext.java
index 9a9ccd5..717e02b 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/TracingContext.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/TracingContext.java
@@ -20,7 +20,7 @@ package org.apache.skywalking.apm.agent.core.context;
import java.util.LinkedList;
import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.skywalking.apm.agent.core.boot.ServiceManager;
import org.apache.skywalking.apm.agent.core.conf.Config;
@@ -37,7 +37,6 @@ import org.apache.skywalking.apm.agent.core.context.trace.TraceSegmentRef;
import org.apache.skywalking.apm.agent.core.context.trace.WithPeerInfo;
import org.apache.skywalking.apm.agent.core.dictionary.DictionaryManager;
import org.apache.skywalking.apm.agent.core.dictionary.DictionaryUtil;
-import org.apache.skywalking.apm.agent.core.dictionary.PossibleFound;
import org.apache.skywalking.apm.agent.core.logging.api.ILog;
import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
import org.apache.skywalking.apm.agent.core.profile.ProfileTaskExecutionService;
@@ -63,12 +62,12 @@ public class TracingContext implements AbstractTracerContext {
private long lastWarningTimestamp = 0;
/**
- * @see {@link ProfileTaskExecutionService}
+ * @see ProfileTaskExecutionService
*/
private static ProfileTaskExecutionService PROFILE_TASK_EXECUTION_SERVICE;
/**
- * @see {@link SamplingService}
+ * @see SamplingService
*/
private static SamplingService SAMPLING_SERVICE;
@@ -82,7 +81,7 @@ public class TracingContext implements AbstractTracerContext {
* storage-structure. <p> I use {@link LinkedList#removeLast()}, {@link LinkedList#addLast(Object)} and {@link
* LinkedList#getLast()} instead of {@link #pop()}, {@link #push(AbstractSpan)}, {@link #peek()}
*/
- private LinkedList<AbstractSpan> activeSpanStack = new LinkedList<AbstractSpan>();
+ private LinkedList<AbstractSpan> activeSpanStack = new LinkedList<>();
/**
* A counter for the next span.
@@ -92,7 +91,10 @@ public class TracingContext implements AbstractTracerContext {
/**
* The counter indicates
*/
- private volatile AtomicInteger asyncSpanCounter;
+ @SuppressWarnings("unused") // updated by ASYNC_SPAN_COUNTER_UPDATER
+ private volatile int asyncSpanCounter;
+ private static final AtomicIntegerFieldUpdater<TracingContext> ASYNC_SPAN_COUNTER_UPDATER =
+ AtomicIntegerFieldUpdater.newUpdater(TracingContext.class, "asyncSpanCounter");
private volatile boolean isRunningInAsyncMode;
private volatile ReentrantLock asyncFinishLock;
@@ -170,7 +172,7 @@ public class TracingContext implements AbstractTracerContext {
entryApplicationInstanceId = ref.getEntryServiceInstanceId();
} else {
if (firstSpan.isEntry()) {
- /**
+ /*
* Since 6.6.0, if first span is not entry span, then this is an internal segment(no RPC),
* rather than an endpoint.
*/
@@ -186,7 +188,7 @@ public class TracingContext implements AbstractTracerContext {
if (!StringUtil.isEmpty(operationName)) {
carrier.setEntryEndpointName(operationName);
} else {
- /**
+ /*
* Since 6.6.0, if first span is not entry span, then this is an internal segment(no RPC),
* rather than an endpoint.
*/
@@ -200,7 +202,7 @@ public class TracingContext implements AbstractTracerContext {
if (firstSpan.isEntry() && !StringUtil.isEmpty(firstSpanOperationName)) {
carrier.setParentEndpointName(firstSpanOperationName);
} else {
- /**
+ /*
* Since 6.6.0, if first span is not entry span, then this is an internal segment(no RPC),
* rather than an endpoint.
*/
@@ -257,7 +259,7 @@ public class TracingContext implements AbstractTracerContext {
entryOperationId = firstSpan.getOperationId();
entryOperationName = firstSpanOperationName;
} else {
- /**
+ /*
* Since 6.6.0, if first span is not entry span, then this is an internal segment(no RPC),
* rather than an endpoint.
*/
@@ -271,7 +273,7 @@ public class TracingContext implements AbstractTracerContext {
if (!StringUtil.isEmpty(entryOperationName)) {
snapshot.setEntryOperationName(entryOperationName);
} else {
- /**
+ /*
* Since 6.6.0, if first span is not entry span, then this is an internal segment(no RPC),
* rather than an endpoint.
*/
@@ -285,7 +287,7 @@ public class TracingContext implements AbstractTracerContext {
if (firstSpan.isEntry() && !StringUtil.isEmpty(firstSpanOperationName)) {
snapshot.setParentOperationName(firstSpanOperationName);
} else {
- /**
+ /*
* Since 6.6.0, if first span is not entry span, then this is an internal segment(no RPC),
* rather than an endpoint.
*/
@@ -337,27 +339,13 @@ public class TracingContext implements AbstractTracerContext {
if (parentSpan != null && parentSpan.isEntry()) {
entrySpan = (AbstractTracingSpan)DictionaryManager.findEndpointSection()
.findOnly(segment.getServiceId(), operationName)
- .doInCondition(new PossibleFound.FoundAndObtain() {
- @Override public Object doProcess(int operationId) {
- return parentSpan.setOperationId(operationId);
- }
- }, new PossibleFound.NotFoundAndObtain() {
- @Override public Object doProcess() {
- return parentSpan.setOperationName(operationName);
- }
- });
+ .doInCondition(parentSpan::setOperationId, () -> parentSpan.setOperationName(operationName));
return entrySpan.start();
} else {
entrySpan = (AbstractTracingSpan)DictionaryManager.findEndpointSection()
.findOnly(segment.getServiceId(), operationName)
- .doInCondition(new PossibleFound.FoundAndObtain() {
- @Override public Object doProcess(int operationId) {
- return new EntrySpan(spanIdGenerator++, parentSpanId, operationId, owner);
- }
- }, new PossibleFound.NotFoundAndObtain() {
- @Override public Object doProcess() {
- return new EntrySpan(spanIdGenerator++, parentSpanId, operationName, owner);
- }
+ .doInCondition(operationId -> new EntrySpan(spanIdGenerator++, parentSpanId, operationId, owner), () -> {
+ return new EntrySpan(spanIdGenerator++, parentSpanId, operationName, owner);
});
entrySpan.start();
return push(entrySpan);
@@ -378,7 +366,7 @@ public class TracingContext implements AbstractTracerContext {
}
AbstractSpan parentSpan = peek();
final int parentSpanId = parentSpan == null ? -1 : parentSpan.getSpanId();
- /**
+ /*
* From v6.0.0-beta, local span doesn't do op name register.
* All op name register is related to entry and exit spans only.
*/
@@ -411,17 +399,9 @@ public class TracingContext implements AbstractTracerContext {
final int parentSpanId = parentSpan == null ? -1 : parentSpan.getSpanId();
exitSpan = (AbstractSpan)DictionaryManager.findNetworkAddressSection()
.find(remotePeer).doInCondition(
- new PossibleFound.FoundAndObtain() {
- @Override
- public Object doProcess(final int peerId) {
- return new ExitSpan(spanIdGenerator++, parentSpanId, operationName, peerId, owner);
- }
- },
- new PossibleFound.NotFoundAndObtain() {
- @Override
- public Object doProcess() {
- return new ExitSpan(spanIdGenerator++, parentSpanId, operationName, remotePeer, owner);
- }
+ peerId -> new ExitSpan(spanIdGenerator++, parentSpanId, operationName, peerId, owner),
+ () -> {
+ return new ExitSpan(spanIdGenerator++, parentSpanId, operationName, remotePeer, owner);
});
push(exitSpan);
}
@@ -473,17 +453,17 @@ public class TracingContext implements AbstractTracerContext {
synchronized (this) {
if (!isRunningInAsyncMode) {
asyncFinishLock = new ReentrantLock();
- asyncSpanCounter = new AtomicInteger(0);
+ ASYNC_SPAN_COUNTER_UPDATER.set(this, 0);
isRunningInAsyncMode = true;
}
}
}
- asyncSpanCounter.addAndGet(1);
+ ASYNC_SPAN_COUNTER_UPDATER.incrementAndGet(this);
return this;
}
@Override public void asyncStop(AsyncSpan span) {
- asyncSpanCounter.addAndGet(-1);
+ ASYNC_SPAN_COUNTER_UPDATER.decrementAndGet(this);
finish();
}
@@ -513,13 +493,13 @@ public class TracingContext implements AbstractTracerContext {
try {
boolean isFinishedInMainThread = activeSpanStack.isEmpty() && running;
if (isFinishedInMainThread) {
- /**
+ /*
* Notify after tracing finished in the main thread.
*/
TracingThreadListenerManager.notifyFinish(this);
}
- if (isFinishedInMainThread && (!isRunningInAsyncMode || asyncSpanCounter.get() == 0)) {
+ if (isFinishedInMainThread && (!isRunningInAsyncMode || asyncSpanCounter == 0)) {
TraceSegment finishedSegment = segment.finish(isLimitMechanismWorking());
/*
* Recheck the segment if the segment contains only one span.
@@ -558,7 +538,7 @@ public class TracingContext implements AbstractTracerContext {
* when the <code>TracingContext</code> finished, and {@link #segment} is ready for further process.
*/
public static class ListenerManager {
- private static List<TracingContextListener> LISTENERS = new LinkedList<TracingContextListener>();
+ private static List<TracingContextListener> LISTENERS = new LinkedList<>();
/**
* Add the given {@link TracingContextListener} to {@link #LISTENERS} list.
@@ -574,7 +554,7 @@ public class TracingContext implements AbstractTracerContext {
* trigger {@link TracingContext.ListenerManager} to notify all {@link #LISTENERS} 's {@link
* TracingContextListener#afterFinished(TraceSegment)}
*
- * @param finishedSegment
+ * @param finishedSegment the segment that has finished
*/
static void notifyFinish(TraceSegment finishedSegment) {
for (TracingContextListener listener : LISTENERS) {
@@ -622,7 +602,7 @@ public class TracingContext implements AbstractTracerContext {
/**
* Add a new Span at the top of 'ActiveSpanStack'
*
- * @param span
+ * @param span the {@code span} to push
*/
private AbstractSpan push(AbstractSpan span) {
activeSpanStack.addLast(span);