
com.newrelic.agent.profile.ProfileTree Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of newrelic-agent Show documentation
Show all versions of newrelic-agent Show documentation
Jar required to run with a java application to monitor performance.
The newest version!
/*
*
* * Copyright 2020 New Relic Corporation. All rights reserved.
* * SPDX-License-Identifier: Apache-2.0
*
*/
package com.newrelic.agent.profile;
import org.json.simple.JSONArray;
import org.json.simple.JSONStreamAware;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* This class holds thread sampling data for threads of a given type.
*
* @see ThreadType
*/
public class ProfileTree implements JSONStreamAware {
private final Map rootSegments = new IdentityHashMap<>();
/**
* A map of stack trace elements to ProfiledMethods. This helps us create fewer {@link ProfiledMethod} instances and
* allows us to use identity hashmaps.
*/
private final Map profiledMethods = new HashMap<>();
private long cpuTime;
public ProfileTree() {
}
/**
* @param stackTraceElement
* @param parent
* @param runnable
* @return a ProfileSegment representing the stack trace element passed in
*/
private ProfileSegment add(StackTraceElement stackTraceElement, ProfileSegment parent, boolean runnable) {
ProfiledMethod method = profiledMethods.get(stackTraceElement);
if (method == null) {
method = ProfiledMethod.newProfiledMethod(stackTraceElement);
if (method != null) {
profiledMethods.put(stackTraceElement, method);
}
}
if (method == null) {
return parent;
}
return add(method, parent, runnable);
}
private ProfileSegment add(ProfiledMethod method, ProfileSegment parent, boolean runnable) {
ProfileSegment result = add(method, parent);
if (runnable) {
result.incrementRunnableCallCount();
} else {
result.incrementNonRunnableCallCount();
}
return result;
}
private ProfileSegment add(ProfiledMethod method, ProfileSegment parent) {
ProfileSegment result;
if (parent == null) {
result = rootSegments.get(method);
if (result == null) {
result = ProfileSegment.newProfileSegment(method);
rootSegments.put(method, result);
}
} else {
result = parent.addChild(method);
}
return result;
}
/**
* Return number of calls to given method from all invocations
*
* @param stackElement
*/
public int getCallCount(StackTraceElement stackElement) {
ProfiledMethod method = ProfiledMethod.newProfiledMethod(stackElement);
if (method == null) {
return 0;
}
int count = 0;
for (ProfileSegment segment : rootSegments.values()) {
count += segment.getCallCount(method);
}
return count;
}
/**
* Returns the number of distinct method invocation nodes in the tree.
*
*/
public int getCallSiteCount() {
int count = 0;
for (ProfileSegment segment : rootSegments.values()) {
count += segment.getCallSiteCount();
}
return count;
}
public Collection getRootSegments() {
return rootSegments.values();
}
public int getRootCount() {
return getRootSegments().size();
}
public int getMethodCount() {
Set methodNames = new HashSet<>();
for (ProfileSegment segment : rootSegments.values()) {
methodNames.addAll(segment.getMethods());
}
return methodNames.size();
}
public void addStackTrace(List stackTraceList, boolean runnable) {
ProfileSegment parent = null;
for (StackTraceElement methodCall : stackTraceList) {
parent = add(methodCall, parent, runnable);
}
}
@Override
public void writeJSONString(Writer out) throws IOException {
Collection rootSegments = getRootSegments();
ArrayList
© 2015 - 2025 Weber Informatics LLC | Privacy Policy