зеркало из https://github.com/microsoft/gctoolkit.git
Transfer of assets to gctoolkit
This commit is contained in:
Родитель
20182053a4
Коммит
3ce8e8bb98
|
@ -0,0 +1,27 @@
|
|||
gclogs/
|
||||
|
||||
# Maven
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
.mvn/timing.properties
|
||||
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
|
||||
.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
# JetBrains IDEs
|
||||
.idea/
|
||||
**/*.iml
|
||||
**/*.ipr
|
||||
**/*.iws
|
||||
out/
|
||||
|
||||
# Mac OS
|
||||
**/.DS_Store
|
||||
|
||||
# vi
|
||||
**/*.swp
|
|
@ -0,0 +1,9 @@
|
|||
# Microsoft Open Source Code of Conduct
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
||||
|
||||
Resources:
|
||||
|
||||
- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
|
||||
- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
|
||||
- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
|
|
@ -0,0 +1,12 @@
|
|||
This project welcomes contributions and suggestions. Most contributions require you to
|
||||
agree to a Contributor License Agreement (CLA) declaring that you have the right to,
|
||||
and actually do, grant us the rights to use your contribution. For details, visit
|
||||
https://cla.microsoft.com.
|
||||
|
||||
When you submit a pull request, a CLA-bot will automatically determine whether you need
|
||||
to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the
|
||||
instructions provided by the bot. You will only need to do this once across all repositories using our CLA.
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
||||
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
|
||||
or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
31
README.md
31
README.md
|
@ -1,3 +1,28 @@
|
|||
# Repository setup required :wave:
|
||||
|
||||
Please visit the website URL :point_right: for this repository to complete the setup of this repository and configure access controls.
|
||||
# Microsoft GCToolKit
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Maven Coordinates
|
||||
|
||||
### Example
|
||||
|
||||
## Build and Test
|
||||
|
||||
The build is vanilla Maven.
|
||||
|
||||
<br/>`mvn clean` - remove build artifacts
|
||||
<br/>`mvn compile` - compile the source code
|
||||
<br/>`mvn test` - run unit tests (this project uses TestNG)
|
||||
<br/>`mvn package` - build the .jar file
|
||||
|
||||
## Contributing
|
||||
|
||||
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, view [Microsoft's CLA](https://cla.microsoft.com).
|
||||
|
||||
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repositories using our CLA.
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
||||
|
||||
## License
|
||||
|
||||
Microsoft JFR Streaming Library is licensed under the [MIT](https://github.com/microsoft/jfr-streaming/blob/master/LICENSE) license.
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.5 BLOCK -->
|
||||
|
||||
## Security
|
||||
|
||||
Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
|
||||
|
||||
If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below.
|
||||
|
||||
## Reporting Security Issues
|
||||
|
||||
**Please do not report security vulnerabilities through public GitHub issues.**
|
||||
|
||||
Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report).
|
||||
|
||||
If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc).
|
||||
|
||||
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc).
|
||||
|
||||
Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
|
||||
|
||||
* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
|
||||
* Full paths of source file(s) related to the manifestation of the issue
|
||||
* The location of the affected source code (tag/branch/commit or direct URL)
|
||||
* Any special configuration required to reproduce the issue
|
||||
* Step-by-step instructions to reproduce the issue
|
||||
* Proof-of-concept or exploit code (if possible)
|
||||
* Impact of the issue, including how an attacker might exploit the issue
|
||||
|
||||
This information will help us triage your report more quickly.
|
||||
|
||||
If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs.
|
||||
|
||||
## Preferred Languages
|
||||
|
||||
We prefer all communications to be in English.
|
||||
|
||||
## Policy
|
||||
|
||||
Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd).
|
||||
|
||||
<!-- END MICROSOFT SECURITY.MD BLOCK -->
|
|
@ -0,0 +1,15 @@
|
|||
# Support
|
||||
|
||||
## How to file issues and get help
|
||||
|
||||
This project uses GitHub Issues to track bugs and feature requests. Please search the existing
|
||||
issues before filing new issues to avoid duplicates. For new issues, file your bug or
|
||||
feature request as a new Issue.
|
||||
|
||||
For help and questions about using this project, please **REPO MAINTAINER: INSERT INSTRUCTIONS HERE
|
||||
FOR HOW TO ENGAGE REPO OWNERS OR COMMUNITY FOR HELP. COULD BE A STACK OVERFLOW TAG OR OTHER
|
||||
CHANNEL. WHERE WILL YOU HELP PEOPLE?**.
|
||||
|
||||
## Microsoft Support Policy
|
||||
|
||||
Support for this **PROJECT or PRODUCT** is limited to the resources listed above.
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.microsoft.censum</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>2.0.1-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>api</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -0,0 +1,68 @@
|
|||
package com.microsoft.censum;
|
||||
|
||||
import com.microsoft.censum.aggregator.Aggregation;
|
||||
import com.microsoft.censum.io.DataSource;
|
||||
import com.microsoft.censum.jvm.JavaVirtualMachine;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashSet;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class Censum {
|
||||
|
||||
private static Logger LOGGER = Logger.getLogger(Censum.class.getName());
|
||||
|
||||
private static JavaVirtualMachine loadJavaVirtualMachine() {
|
||||
try {
|
||||
// TODO: property for to allow override of default implementation.
|
||||
Class<?> clazz =
|
||||
Class.forName("com.microsoft.censum.vertx.jvm.DefaultJavaVirtualMachine", true, Thread.currentThread().getContextClassLoader());
|
||||
Constructor<?> constructor = clazz.getConstructor();
|
||||
JavaVirtualMachine javaVirtualMachine = (JavaVirtualMachine) constructor.newInstance();
|
||||
return javaVirtualMachine;
|
||||
} catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException |
|
||||
InstantiationException | IllegalAccessException e) {
|
||||
LOGGER.log(Level.SEVERE, "Cannot load \"com.microsoft.censum.vertx.jvm.DefaultJavaVirtualMachine\"",e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static final Set<Class<? extends Aggregation>> aggregationsFromServiceLoader;
|
||||
|
||||
static {
|
||||
aggregationsFromServiceLoader = new HashSet<>();
|
||||
ServiceLoader<Aggregation> serviceLoader = ServiceLoader.load(Aggregation.class);
|
||||
serviceLoader.stream()
|
||||
.map(ServiceLoader.Provider::get)
|
||||
.map(Aggregation::getClass)
|
||||
.forEach(aggregationsFromServiceLoader::add);
|
||||
}
|
||||
|
||||
private final Set<Class<? extends Aggregation>> registeredAggregations;
|
||||
public Censum() {
|
||||
// Allow for adding aggregations from source code,
|
||||
// but don't corrupt the ones loaded by the service loader
|
||||
this.registeredAggregations = new HashSet<>(aggregationsFromServiceLoader);
|
||||
}
|
||||
|
||||
public void registerAggregation(Class<? extends Aggregation> aggregationClass) {
|
||||
registeredAggregations.add(aggregationClass);
|
||||
}
|
||||
|
||||
public JavaVirtualMachine analyze(DataSource<?> dataSource) {
|
||||
// Potential NPE, but would have logged if there was trouble creating the instance.
|
||||
JavaVirtualMachine javaVirtualMachine = loadJavaVirtualMachine();
|
||||
try {
|
||||
Method analyze = javaVirtualMachine.getClass().getMethod("analyze", Set.class, DataSource.class);
|
||||
analyze.invoke(javaVirtualMachine, this, dataSource);
|
||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
||||
LOGGER.log(Level.SEVERE, "Cannot invoke analyze method",e);
|
||||
}
|
||||
return javaVirtualMachine;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.microsoft.censum.aggregator;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* This annotation is used by implementations of Aggregator to indicate
|
||||
* to the AggregationRegistry the source of the events being aggregated.
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
/**
|
||||
* This annotation is used by implementations of Aggregator to indicate
|
||||
* to the AggregatorRegistry the source of the events being aggregated.
|
||||
* @see AggregatorRegistry#getAggregators(EventSource)
|
||||
*/
|
||||
public @interface Aggregates {
|
||||
/**
|
||||
* Indicate the source of events being aggregated by an Aggregator.
|
||||
* @return An array of EventSource
|
||||
*/
|
||||
EventSource[] value();
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.aggregator;
|
||||
|
||||
public interface Aggregation {
|
||||
|
||||
boolean hasWarning();
|
||||
|
||||
boolean isEmpty();
|
||||
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.aggregator;
|
||||
|
||||
import com.microsoft.censum.event.jvm.JVMEvent;
|
||||
import com.microsoft.censum.event.jvm.JVMTermination;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* An Aggregator consumes a JVMEvent and accumulates counts and stats about that JVMEvent.
|
||||
* JVMEvents are {@link #consume(JVMEvent) consumed} and dispatched to methods written to
|
||||
* handle a particular kind of event. Aggregators should {@link #register(Class, Consumer)}
|
||||
* the event handlers in their constructor.
|
||||
* <code>
|
||||
* <pre>
|
||||
*public class G1GCCauseAggregator extends GCCauseAggregator {
|
||||
*
|
||||
* public G1GCCauseAggregator() {
|
||||
* register(G1Young.class, this::process);
|
||||
* register(G1Mixed.class, this::process);
|
||||
* register(G1YoungInitialMark.class, this::process);
|
||||
* register(G1FullGC.class, this::process);
|
||||
* }
|
||||
*
|
||||
* private void process(G1Young collection) {
|
||||
* record(GarbageCollectionTypes.Young, collection.getGCCause());
|
||||
* }
|
||||
*
|
||||
* private void process(G1Mixed collection) {
|
||||
* record(GarbageCollectionTypes.Mixed, collection.getGCCause());
|
||||
* }
|
||||
*
|
||||
* private void process(G1YoungInitialMark collection) {
|
||||
* record(GarbageCollectionTypes.G1GCYoungInitialMark, collection.getGCCause());
|
||||
* }
|
||||
*
|
||||
* private void process(G1FullGC collection) {
|
||||
* record(GarbageCollectionTypes.FullGC, collection.getGCCause());
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* </code>
|
||||
*/
|
||||
public abstract class Aggregator<A extends Aggregation> {
|
||||
|
||||
private final A aggregation;
|
||||
|
||||
/// JVMEventDispatcher manages all of the registered events and event consumers
|
||||
private final JVMEventDispatcher jvmEventDispatcher = new JVMEventDispatcher();
|
||||
volatile private boolean done = false;
|
||||
|
||||
/**
|
||||
* Subclass only.
|
||||
*/
|
||||
protected Aggregator(A aggregation) {
|
||||
this.aggregation = aggregation;
|
||||
register(JVMTermination.class,this::terminationHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the {@link Aggregation} that collates the data
|
||||
* which is collected by this {@code Aggregator}.
|
||||
* @return The Aggregator's corresponding Aggregation
|
||||
*/
|
||||
public A aggregation() {
|
||||
return aggregation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a JVMEvent class and the method in the Aggregator sub-class that handles it.
|
||||
* If the JVMEvent class is a super-class of other event types, then the Consumer is called
|
||||
* for all sub-classes of that JVMEvent class, unless a Consumer for a more specific event class
|
||||
* is registered.
|
||||
* <p>
|
||||
* The typical pattern is to call this method from the constructor of the Aggregator sub-class.
|
||||
* <code><pre>
|
||||
* register(G1Young.class, this::process);
|
||||
* </pre></code>
|
||||
* The {@code Consumer} for this example would be coded as:
|
||||
* <code><pre>
|
||||
* private void process(G1Young collection) {...}
|
||||
* </pre></code>
|
||||
* Where the body of the method would pull out and aggregate the relevant data from the event.
|
||||
* @param eventClass the Class of the JVMEvent type to register.
|
||||
* @param process the handler which processes the event
|
||||
*/
|
||||
protected <E extends JVMEvent> void register(Class<E> eventClass, Consumer<? super E> process) {
|
||||
jvmEventDispatcher.register(eventClass, process);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method consumes a JVMEvent and dispatches it to the
|
||||
* {@link #register(Class, Consumer) registered consumer}.
|
||||
* @param event an event to be processed
|
||||
*/
|
||||
public <R extends JVMEvent> void consume(R event) {
|
||||
jvmEventDispatcher.dispatch(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* The JVMTermination event signals the end of processing of a log file.
|
||||
* @param event JVMTermination is a sentinel for the end of log processing.
|
||||
*/
|
||||
private void terminationHandler(JVMTermination event) {
|
||||
if (!done) done = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether all events have been processed by the Aggregator.
|
||||
* @return {@code true} if this Aggregator is done processing events.
|
||||
*/
|
||||
public boolean isDone() {
|
||||
return done;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package com.microsoft.censum.aggregator;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* An implementation of an Aggregation collates data from an Aggregator.
|
||||
* This annotation is used on an Aggregation to tell Censum which
|
||||
* Aggregator produces the data the Aggregation collates.
|
||||
*
|
||||
* In this example, there is a PauseTimeAggegator which receives pause time events
|
||||
* from Censum. The PauseTimeAggregator extracts the cause, the time the event
|
||||
* occurred, and the duration of the event and calls the PauseTimeAggregation method.
|
||||
*
|
||||
* An implementation of PauseTimeAggregation is able to collate the data in a way
|
||||
* that makes sense for how the data is to be viewed. For example: one may want to
|
||||
* summarize the data as a histogram, or one may want to collect a series of data
|
||||
* for plotting.
|
||||
* <pre>
|
||||
* {@code
|
||||
* @Aggregates({EventSource.G1GC. EventSource.Generational, EventSource.ZGC, EventSource.Shenandoah})
|
||||
* public class PauseTimeAggregator extends Aggregator<PauseTimeAggregation> {
|
||||
* ...
|
||||
* }
|
||||
* @Collates(PauseTimeAggregator.class)
|
||||
* public interface PauseTimeAggregation extends Aggregation {
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* public class PauseTimeSummary implements PauseTimeAggregation {
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* public class PauseTimeGraph implements PauseTimeAggregation {
|
||||
* ...
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface Collates {
|
||||
Class<? extends Aggregator<?>> value();
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.microsoft.censum.aggregator;
|
||||
|
||||
/**
|
||||
* EventSource indicates to the source of the GC events
|
||||
* that an Aggregator is meant to process.
|
||||
* @see Aggregates
|
||||
*/
|
||||
public enum EventSource {
|
||||
GENERATIONAL,
|
||||
G1GC,
|
||||
SHENANDOAH,
|
||||
ZGC,
|
||||
SAFEPOINT,
|
||||
SURVIVOR,
|
||||
TENURED;
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.aggregator;
|
||||
|
||||
import com.microsoft.censum.event.jvm.JVMEvent;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class JVMEventDispatcher {
|
||||
private final Map<Class<? extends JVMEvent>, Consumer<JVMEvent>> eventConsumers = new HashMap<>();
|
||||
|
||||
private final Consumer<JVMEvent> nopConsumer = (evt) -> {
|
||||
};
|
||||
|
||||
private <R extends JVMEvent> Consumer<JVMEvent> getConsumerForClass(Class<R> eventClass) {
|
||||
Class<? extends JVMEvent> clazz = eventClass;
|
||||
|
||||
//Fast path that should hit after the event has been seen for the first time
|
||||
Consumer<JVMEvent> eventConsumer = eventConsumers.get(clazz);
|
||||
if (eventConsumer != null) {
|
||||
return eventConsumer;
|
||||
}
|
||||
|
||||
do {
|
||||
eventConsumer = eventConsumers.get(clazz);
|
||||
|
||||
if (eventConsumer != null) {
|
||||
|
||||
if (eventClass != clazz) {
|
||||
//optimisation to avoid walking up the class tree every time, if we get a hit on
|
||||
//R maps to eventConsumer, just put it in the map and it will fetch first time in the future
|
||||
eventConsumers.put(eventClass, eventConsumer);
|
||||
}
|
||||
|
||||
//visit the most specific ONLY
|
||||
return eventConsumer;
|
||||
}
|
||||
|
||||
if (clazz == JVMEvent.class) {
|
||||
// Hit the top of the hierachy
|
||||
break;
|
||||
} else {
|
||||
//Unfortunate cast but assuming register has done its job it is impossible for this cast to fail
|
||||
clazz = (Class<? extends JVMEvent>) clazz.getSuperclass();
|
||||
}
|
||||
} while (clazz != null);
|
||||
|
||||
//no handler for eventClass so lets put in a stub so we dont have to figure this out on every event
|
||||
eventConsumers.put(eventClass, nopConsumer);
|
||||
return nopConsumer;
|
||||
}
|
||||
|
||||
public <R extends JVMEvent> void register(Class<R> eventClass, Consumer<? super R> process) {
|
||||
eventConsumers.put(eventClass, (Consumer<JVMEvent>)process);
|
||||
}
|
||||
|
||||
public <R extends JVMEvent> void dispatch(R event) {
|
||||
getConsumerForClass(event.getClass()).accept(event);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package com.microsoft.censum.collections;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.util.Collections.unmodifiableList;
|
||||
|
||||
public class CensumXYDataSet {
|
||||
|
||||
protected List<Point> dataSeries;
|
||||
|
||||
public CensumXYDataSet() {
|
||||
dataSeries = new ArrayList<>();
|
||||
}
|
||||
|
||||
public CensumXYDataSet(CensumXYDataSet series) {
|
||||
dataSeries = new ArrayList<>(series.getItems());
|
||||
|
||||
}
|
||||
|
||||
public void add(Number x, Number y) {
|
||||
dataSeries.add(new Point(x, y));
|
||||
}
|
||||
|
||||
public void add(Point item) {
|
||||
dataSeries.add(item);
|
||||
}
|
||||
|
||||
protected void addAll(List<Point> items) {
|
||||
dataSeries.addAll(items);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return dataSeries.isEmpty();
|
||||
}
|
||||
|
||||
public List<Point> getItems() {
|
||||
return unmodifiableList(dataSeries);
|
||||
}
|
||||
|
||||
public CensumXYDataSet scaleSeries(double scaleFactor) {
|
||||
CensumXYDataSet scaled = new CensumXYDataSet();
|
||||
for (Point item : dataSeries) {
|
||||
scaled.add(item.getX(), item.getY().doubleValue() * scaleFactor);
|
||||
}
|
||||
return scaled;
|
||||
}
|
||||
|
||||
public double max() {
|
||||
return dataSeries.stream().map(Point::getY).mapToDouble(Number::doubleValue).max().getAsDouble();
|
||||
}
|
||||
|
||||
public CensumXYDataSet scaleAndTranslateXAxis(double scale, double offset) {
|
||||
CensumXYDataSet translatedSeries = new CensumXYDataSet();
|
||||
for (Point dataPoint : dataSeries) {
|
||||
double scaledXCoordinate = (scale * dataPoint.getX().doubleValue()) + offset;
|
||||
translatedSeries.add(scaledXCoordinate, dataPoint.getY());
|
||||
}
|
||||
return translatedSeries;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return dataSeries.size();
|
||||
}
|
||||
|
||||
public Stream<Point> stream() {
|
||||
return dataSeries.stream();
|
||||
}
|
||||
|
||||
public static class Point {
|
||||
|
||||
final private Number x;
|
||||
final private Number y;
|
||||
|
||||
public Point(Number x, Number y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public Number getX() {
|
||||
return x;
|
||||
}
|
||||
public Number getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return x + "," + y;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event;
|
||||
|
||||
public class CPUSummary {
|
||||
|
||||
private final double user;
|
||||
private final double kernel;
|
||||
private final double wallClock;
|
||||
|
||||
public CPUSummary(double user, double kernel, double wallClock) {
|
||||
this.user = user;
|
||||
this.kernel = kernel;
|
||||
this.wallClock = wallClock;
|
||||
}
|
||||
|
||||
public double getUser() {
|
||||
return this.user;
|
||||
}
|
||||
|
||||
public double getKernel() {
|
||||
return this.kernel;
|
||||
}
|
||||
|
||||
public double getWallClock() {
|
||||
return this.wallClock;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "[Times: user=" + user + " sys=" + kernel + ", real=" + wallClock + " secs]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event;
|
||||
|
||||
/**
|
||||
* There are causes for Garbage Collection, this is a representation of the
|
||||
* causes that a GC log file can hold.
|
||||
*/
|
||||
public enum GCCause {
|
||||
|
||||
JAVA_LANG_SYSTEM("System.gc()"),
|
||||
DIAGNOSTIC_COMMAND("Diagnostic Command"),
|
||||
FULL_GC_ALOT("FullGCALot"),
|
||||
SCAVENGE_ALOT("ScavengeAlot"),
|
||||
ALLOCATION_PROFILER("Allocation Profiler"),
|
||||
JVMTI_FORCE_GC("JvmtiEnv ForceGarbageCollection"),
|
||||
GC_LOCKER("GCLocker Initiated GC"),
|
||||
HEAP_INSPECTION("Heap Inspection Initiated GC"),
|
||||
HEAP_DUMP("Heap Dump Initiated GC"),
|
||||
NO_GC("No GC"),
|
||||
ALLOCATION_FAILURE("Allocation Failure"),
|
||||
TENURED_GENERATION_FULL("Tenured Generation Full"),
|
||||
METADATA_GENERATION_THRESHOLD("Metadata GC Threshold"),
|
||||
PERMANENT_GENERATION_FULL("Permanent Generation Full"),
|
||||
CMS_GENERATION_FULL("CMS Generation Full"),
|
||||
CMS_INITIAL_MARK("CMS Initial Mark"),
|
||||
CMS_FINAL_REMARK("CMS Final Remark"),
|
||||
CMS_CONCURRENT_MARK("CMS Concurrent Mark"),
|
||||
CMS_FAILURE("CMS Failure"),
|
||||
OLD_GENERATION_EXPANDED_ON_LAST_SCAVENGE("Old Generation Expanded On Last Scavenge"),
|
||||
OLD_GENERATION_TOO_FULL_TO_SCAVENGE("Old Generation Too Full To Scavenge"),
|
||||
ADAPTIVE_SIZE_POLICY("Ergonomics"),
|
||||
G1_EVACUATION_PAUSE("G1 Evacuation Pause"),
|
||||
G1_HUMONGOUS_ALLOCATION("G1 Humongous Allocation"),
|
||||
LAST_DITCH_COLLECTION("Last ditch collection"),
|
||||
LAST_GC_CAUSE("ILLEGAL VALUE - last gc cause - ILLEGAL VALUE"),
|
||||
UNKNOWN_GCCAUSE("unknown GCCause"),
|
||||
PROMOTION_FAILED("promotion failed"),
|
||||
UPDATE_ALLOCATION_CONTEXT_STATS("Update Allocation Context Stats"),
|
||||
GCCAUSE_NOT_SET("Missing GC Cause"),
|
||||
// Additional GCCauses not found in gcause.cpp
|
||||
CONCURRENT_MARK_STACK_OVERFLOW("Concurrent Mark Stack Overflow"),
|
||||
G1GC_YOUNG("young"),
|
||||
|
||||
//JDK 11
|
||||
WHITEBOX_YOUNG("WhiteBox Initiated Young GC"),
|
||||
WHITEBOX_CONCURRENT_MARK("WhiteBox Initiated Concurrent Mark"),
|
||||
WHITEBOX_FULL("WhiteBox Initiated Full GC"),
|
||||
META_CLEAR_SOFT_REF("Metadata GC Clear Soft References"),
|
||||
TIMER("Timer"),
|
||||
WARMUP("Warmup"),
|
||||
ALLOC_RATE("Allocation Rate"),
|
||||
ALLOC_STALL("Allocation Stall"),
|
||||
PROACTIVE("Proactive");
|
||||
|
||||
private final String label;
|
||||
|
||||
GCCause(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import static com.microsoft.censum.event.GCCause.*;
|
||||
|
||||
public class GCCauses {
|
||||
|
||||
private final static HashMap<String, GCCause> GC_CAUSES;
|
||||
|
||||
static {
|
||||
GC_CAUSES = new HashMap<String, GCCause>(50);
|
||||
|
||||
GC_CAUSES.put(GCCause.JAVA_LANG_SYSTEM.getLabel(), GCCause.JAVA_LANG_SYSTEM);
|
||||
GC_CAUSES.put("System", GCCause.JAVA_LANG_SYSTEM);
|
||||
GC_CAUSES.put(GCCause.DIAGNOSTIC_COMMAND.getLabel(), GCCause.JAVA_LANG_SYSTEM);
|
||||
GC_CAUSES.put(GCCause.FULL_GC_ALOT.getLabel(), GCCause.FULL_GC_ALOT);
|
||||
GC_CAUSES.put(GCCause.SCAVENGE_ALOT.getLabel(), GCCause.SCAVENGE_ALOT);
|
||||
GC_CAUSES.put(GCCause.ALLOCATION_PROFILER.getLabel(), GCCause.ALLOCATION_PROFILER);
|
||||
GC_CAUSES.put(GCCause.JVMTI_FORCE_GC.getLabel(), GCCause.JVMTI_FORCE_GC);
|
||||
GC_CAUSES.put(GCCause.GC_LOCKER.getLabel(), GCCause.GC_LOCKER);
|
||||
GC_CAUSES.put(GCCause.HEAP_INSPECTION.getLabel(), GCCause.HEAP_INSPECTION);
|
||||
GC_CAUSES.put(GCCause.HEAP_DUMP.getLabel(), GCCause.HEAP_DUMP);
|
||||
GC_CAUSES.put(GCCause.NO_GC.getLabel(), GCCause.NO_GC);
|
||||
GC_CAUSES.put(GCCause.ALLOCATION_FAILURE.getLabel(), GCCause.ALLOCATION_FAILURE);
|
||||
GC_CAUSES.put(GCCause.TENURED_GENERATION_FULL.getLabel(), GCCause.TENURED_GENERATION_FULL);
|
||||
GC_CAUSES.put(GCCause.METADATA_GENERATION_THRESHOLD.getLabel(), GCCause.METADATA_GENERATION_THRESHOLD);
|
||||
GC_CAUSES.put(GCCause.PERMANENT_GENERATION_FULL.getLabel(), GCCause.PERMANENT_GENERATION_FULL);
|
||||
GC_CAUSES.put(GCCause.CMS_GENERATION_FULL.getLabel(), GCCause.CMS_GENERATION_FULL);
|
||||
GC_CAUSES.put(GCCause.CMS_INITIAL_MARK.getLabel(), GCCause.CMS_INITIAL_MARK);
|
||||
GC_CAUSES.put(GCCause.CMS_FINAL_REMARK.getLabel(), GCCause.CMS_FINAL_REMARK);
|
||||
GC_CAUSES.put(GCCause.CMS_CONCURRENT_MARK.getLabel(), GCCause.CMS_CONCURRENT_MARK);
|
||||
GC_CAUSES.put(GCCause.OLD_GENERATION_EXPANDED_ON_LAST_SCAVENGE.getLabel(), GCCause.OLD_GENERATION_EXPANDED_ON_LAST_SCAVENGE);
|
||||
GC_CAUSES.put(GCCause.OLD_GENERATION_TOO_FULL_TO_SCAVENGE.getLabel(), GCCause.OLD_GENERATION_TOO_FULL_TO_SCAVENGE);
|
||||
GC_CAUSES.put(GCCause.ADAPTIVE_SIZE_POLICY.getLabel(), GCCause.ADAPTIVE_SIZE_POLICY);
|
||||
GC_CAUSES.put(GCCause.G1_EVACUATION_PAUSE.getLabel(), GCCause.G1_EVACUATION_PAUSE);
|
||||
GC_CAUSES.put(GCCause.G1_HUMONGOUS_ALLOCATION.getLabel(), GCCause.G1_HUMONGOUS_ALLOCATION);
|
||||
GC_CAUSES.put(GCCause.LAST_DITCH_COLLECTION.getLabel(), GCCause.LAST_DITCH_COLLECTION);
|
||||
GC_CAUSES.put(GCCause.LAST_GC_CAUSE.getLabel(), GCCause.LAST_GC_CAUSE);
|
||||
GC_CAUSES.put(GCCause.UNKNOWN_GCCAUSE.getLabel(), GCCause.UNKNOWN_GCCAUSE);
|
||||
GC_CAUSES.put(GCCause.GCCAUSE_NOT_SET.getLabel(), GCCause.GCCAUSE_NOT_SET);
|
||||
GC_CAUSES.put(GCCause.CMS_FAILURE.getLabel(), GCCause.CMS_FAILURE);
|
||||
GC_CAUSES.put(GCCause.LAST_GC_CAUSE.getLabel(), GCCause.LAST_GC_CAUSE);
|
||||
GC_CAUSES.put(GCCause.PROMOTION_FAILED.getLabel(), GCCause.PROMOTION_FAILED);
|
||||
GC_CAUSES.put(GCCause.UPDATE_ALLOCATION_CONTEXT_STATS.getLabel(), GCCause.UPDATE_ALLOCATION_CONTEXT_STATS);
|
||||
// Additional GCCauses not found in gcause.cpp
|
||||
GC_CAUSES.put(GCCause.CONCURRENT_MARK_STACK_OVERFLOW.getLabel(), GCCause.CONCURRENT_MARK_STACK_OVERFLOW);
|
||||
GC_CAUSES.put(GCCause.G1GC_YOUNG.getLabel(), GCCause.G1GC_YOUNG);
|
||||
//JDK 11+
|
||||
GC_CAUSES.put(WHITEBOX_YOUNG.getLabel(), WHITEBOX_YOUNG);
|
||||
GC_CAUSES.put(WHITEBOX_CONCURRENT_MARK.getLabel(), WHITEBOX_CONCURRENT_MARK);
|
||||
GC_CAUSES.put(WHITEBOX_FULL.getLabel(), WHITEBOX_FULL);
|
||||
GC_CAUSES.put(META_CLEAR_SOFT_REF.getLabel(), META_CLEAR_SOFT_REF);
|
||||
GC_CAUSES.put(TIMER.getLabel(), TIMER);
|
||||
GC_CAUSES.put(WARMUP.getLabel(), WARMUP);
|
||||
GC_CAUSES.put(ALLOC_RATE.getLabel(), ALLOC_RATE);
|
||||
GC_CAUSES.put(ALLOC_STALL.getLabel(), ALLOC_STALL);
|
||||
GC_CAUSES.put(PROACTIVE.getLabel(), PROACTIVE);
|
||||
}
|
||||
|
||||
public static GCCause get(String gcCauseName) {
|
||||
|
||||
GCCause cause;
|
||||
if (gcCauseName == null) {
|
||||
cause = GCCause.GCCAUSE_NOT_SET;
|
||||
} else {
|
||||
String lookup = gcCauseName.trim();
|
||||
cause = GC_CAUSES.get(lookup.substring(1, lookup.length() - 1));
|
||||
if (cause == null) {
|
||||
cause = GCCause.GCCAUSE_NOT_SET;
|
||||
}
|
||||
}
|
||||
|
||||
return cause;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
FULL_GC_ALOT("FullGCALot"),
|
||||
SCAVENGE_ALOT("ScavengeAlot"),
|
||||
ALLOCATION_PROFILER("Allocation Profiler"),
|
||||
JVMTI_FORCE_GC("JvmtiEnv ForceGarbageCollection"),
|
||||
GC_LOCKER("GCLocker Initiated GC"),
|
||||
HEAP_INSPECTION("Heap Inspection Initiated GC"),
|
||||
HEAP_DUMP("Heap Dump Initiated GC"),
|
||||
NO_GC("No GC"),
|
||||
ALLOCATION_FAILURE("Allocation Failure"),
|
||||
TENURED_GENERATION_FULL("Tenured Generation Full"),
|
||||
METADATA_GENERATION_THRESHOLD("Metadata GC Threshold"),
|
||||
PERMANENT_GENERATION_FULL("Permanent Generation Full"),
|
||||
CMS_GENERATION_FULL("CMS Generation Full"),
|
||||
CMS_INITIAL_MARK("CMS Initial Mark"),
|
||||
CMS_FINAL_REMARK("CMS Final Remark"),
|
||||
CMS_CONCURRENT_MARK("CMS Concurrent Mark"),
|
||||
CMS_FAILURE("CMS Failure"),
|
||||
OLD_GENERATION_EXPANDED_ON_LAST_SCAVENGE("Old Generation Expanded On Last Scavenge"),
|
||||
OLD_GENERATION_TOO_FULL_TO_SCAVENGE("Old Generation Too Full To Scavenge"),
|
||||
ADAPTIVE_SIZE_POLICY("Ergonomics"),
|
||||
G1_EVACUATION_PAUSE("G1 Evacuation Pause"),
|
||||
G1_HUMONGOUS_ALLOCATION("G1 Humongous Allocation"),
|
||||
LAST_DITCH_COLLECTION("Last ditch collection"),
|
||||
LAST_GC_CAUSE("ILLEGAL VALUE - last gc cause - ILLEGAL VALUE"),
|
||||
UNKNOWN_GCCAUSE("unknown GCCause"),
|
||||
PROMOTION_FAILED("promotion failed"),
|
||||
UPDATE_ALLOCATION_CONTEXT_STATS("Update Allocation Context Stats"),
|
||||
GCCAUSE_NOT_SET("Missing GC Cause"),
|
||||
|
||||
//JDK 11
|
||||
WHITEBOX_YOUNG("WhiteBox Initiated Young GC"),
|
||||
WHITEBOX_CONCURRENT_MARK("WhiteBox Initiated Concurrent Mark"),
|
||||
WHITEBOX_FULL("WhiteBox Initiated Full GC"),
|
||||
META_CLEAR_SOFT_REF("Metadata GC Clear Soft References"),
|
||||
TIMER("Timer"),
|
||||
WARMUP("Warmup"),
|
||||
ALLOC_RATE("Allocation Rate"),
|
||||
ALLOC_STALL("Allocation Stall"),
|
||||
PROACTIVE("Proactive");
|
||||
*/
|
|
@ -0,0 +1,100 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event;
|
||||
|
||||
import com.microsoft.censum.event.jvm.JVMEvent;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
/**
|
||||
* A GCEvent is something that happens in the GC sub system that is captured in
|
||||
* the log, e.g. a Full GC
|
||||
* <p>
|
||||
* A GCEvent has meta data which it expects to be overridden, e.g. whether or
|
||||
* not it was a young collection
|
||||
*/
|
||||
abstract public class GCEvent extends JVMEvent {
|
||||
|
||||
static final double TIMESTAMP_THRESHOLD = 1.0E-6;
|
||||
private GarbageCollectionTypes gcType;
|
||||
private GCCause cause;
|
||||
|
||||
protected GCEvent(DateTimeStamp timeStamp, GarbageCollectionTypes gcType, GCCause cause, double duration) {
|
||||
super(timeStamp, duration);
|
||||
this.gcType = gcType;
|
||||
this.cause = cause;
|
||||
}
|
||||
|
||||
protected GCEvent(DateTimeStamp timeStamp, double duration) {
|
||||
this(timeStamp, GarbageCollectionTypes.Unknown, GCCause.UNKNOWN_GCCAUSE, duration);
|
||||
}
|
||||
|
||||
protected GCEvent(DateTimeStamp timeStamp, GCCause cause, double duration) {
|
||||
this(timeStamp, GarbageCollectionTypes.Unknown, cause, duration);
|
||||
}
|
||||
|
||||
protected GCEvent(DateTimeStamp timeStamp, GarbageCollectionTypes gcType, double duration) {
|
||||
this(timeStamp, gcType, GCCause.UNKNOWN_GCCAUSE, duration);
|
||||
}
|
||||
|
||||
public void setGCCause(GCCause cause) {
|
||||
this.cause = cause;
|
||||
}
|
||||
|
||||
public GCCause getGCCause() {
|
||||
return this.cause;
|
||||
}
|
||||
|
||||
public GarbageCollectionTypes getGarbageCollectionType() {
|
||||
return gcType;
|
||||
}
|
||||
|
||||
public boolean isZGC() { return false; }
|
||||
|
||||
public boolean isYoung() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isFull() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isConcurrent() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isG1Young() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isG1Mixed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isG1Concurrent() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isSystemGC() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isConcurrentModeFailure() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isConcurrentModeInterrupted() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean withinThreshold(final double x, final double y) {
|
||||
return TIMESTAMP_THRESHOLD > Math.abs(x - y);
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) return true;
|
||||
GCEvent gcEvent = (GCEvent) o;
|
||||
return gcType.getLabel().equals(gcEvent.gcType.getLabel())
|
||||
&& withinThreshold(getDateTimeStamp().getTimeStamp(), gcEvent.getDateTimeStamp().getTimeStamp())
|
||||
&& withinThreshold(getDuration(), gcEvent.getDuration());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event;
|
||||
|
||||
/**
|
||||
* Representation of GC Collection Events
|
||||
*/
|
||||
public enum GarbageCollectionTypes {
|
||||
|
||||
GC("GC"),
|
||||
Young("Young"),
|
||||
FullGC("Full GC"),
|
||||
Full("FUll GC"),
|
||||
SystemGC("System.gc()"),
|
||||
PSYoungGen("PSYoungGen"),
|
||||
ScavengeBeforeFull("PSYoungGen (System)"),
|
||||
PSFull("PSFull"),
|
||||
DefNew("DefNew"),
|
||||
ParNew("ParNew"),
|
||||
ParNewPromotionFailed("ParNew (promotion failed)"),
|
||||
ConcurrentModeFailure("Concurrent mode failure"),
|
||||
ConcurrentModeInterrupted("Concurrent mode interrupted"),
|
||||
InitialMark("Initial mark"),
|
||||
Initial_Mark("Initial Mark"),
|
||||
Remark("Remark"),
|
||||
ConcurrentPhase("CMS Concurrent Phase"),
|
||||
CMSPausePhase("CMS Pause Phase"),
|
||||
ConcurrentMark("Concurrent mark"),
|
||||
Concurrent_Mark("Mark"),
|
||||
Concurrent_Preclean("Concurrent preclean"),
|
||||
//G1ConcurrentPreclean("Preclean"),
|
||||
Abortable_Preclean("Concurrent abortable preclean"),
|
||||
Concurrent_Sweep("Concurrent sweep"),
|
||||
Concurrent_Reset("Concurrent reset"),
|
||||
Mixed("Mixed"),
|
||||
//G1GCFull("G1GC Full"),
|
||||
Concurrent_Cycle("Concurrent Cycle"),
|
||||
ConcurrentClearClaimedMarks("Clear Claimed Marks"),
|
||||
ConcurrentScanRootRegions("Scan Root Regions"),
|
||||
//ConcurrentMarkFromRoots("Mark From Roots"),
|
||||
ConcurrentCreateLiveData("Create Live Data"),
|
||||
ConcurrentCompleteCleanup("Complete Cleanup"),
|
||||
ConcurrentCleanupForNextMark("Cleanup for Next Mark"),
|
||||
ConcurrentStringDeduplication("G1GC Concurrent String deduplication"),
|
||||
ConcurrentRootRegionScan("G1GC Root Region Scan"),
|
||||
G1GCRemark("G1GC Remark"),
|
||||
G1GCCleanup("G1GC Cleanup"),
|
||||
G1GCConcurrentCleanup("G1GC concurrent cleanup"),
|
||||
G1ConcurrentMarkResetForOverflow("G1GC Concurrent Mark Reset for Overflow"),
|
||||
G1ConcurrentRebuildRememberedSets("Rebuild Remembered Sets"),
|
||||
G1GCYoungInitialMark("G1GC Young Initial mark"),
|
||||
G1GCMixedInitialMark("G1GC Mixed Initial mark"),
|
||||
G1GCConcurrentMark("G1GC Concurrent mark"),
|
||||
G1GCFull("Full"),
|
||||
G1Trap("G1GC Trap"),
|
||||
Unknown("Unknown"),
|
||||
ZGCCycle("ZGC"),
|
||||
Shenandoah("Shenandoah");
|
||||
|
||||
private final String label;
|
||||
|
||||
GarbageCollectionTypes(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public static GarbageCollectionTypes fromLabel(String label) {
|
||||
for (GarbageCollectionTypes gcType : GarbageCollectionTypes.values()) {
|
||||
if (gcType.label.equals(label))
|
||||
return gcType;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event;
|
||||
|
||||
public class MemoryPoolSummary {
|
||||
|
||||
private long occupancyBeforeCollection;
|
||||
private long sizeBeforeCollection;
|
||||
private long occupancyAfterCollection;
|
||||
private long sizeAfterCollection;
|
||||
|
||||
public MemoryPoolSummary(long occupancyBeforeCollection, long sizeBeforeCollection, long occupancyAfterCollection, long sizeAfterCollection) {
|
||||
this.occupancyBeforeCollection = occupancyBeforeCollection;
|
||||
this.sizeBeforeCollection = sizeBeforeCollection;
|
||||
this.occupancyAfterCollection = occupancyAfterCollection;
|
||||
this.sizeAfterCollection = sizeAfterCollection;
|
||||
}
|
||||
|
||||
public MemoryPoolSummary(long occupancyBeforeCollection, long occupancyAfterCollection, long sizeAfterCollection) {
|
||||
this(occupancyBeforeCollection, sizeAfterCollection, occupancyAfterCollection, sizeAfterCollection);
|
||||
}
|
||||
|
||||
public long getOccupancyBeforeCollection() {
|
||||
return this.occupancyBeforeCollection;
|
||||
}
|
||||
|
||||
public long getOccupancyAfterCollection() {
|
||||
return this.occupancyAfterCollection;
|
||||
}
|
||||
|
||||
public long getSizeBeforeCollection() {
|
||||
return this.sizeBeforeCollection;
|
||||
}
|
||||
|
||||
public long getSizeAfterCollection() {
|
||||
return this.sizeAfterCollection;
|
||||
}
|
||||
|
||||
public MemoryPoolSummary minus(MemoryPoolSummary memoryPoolSummary) {
|
||||
return new MemoryPoolSummary(getOccupancyBeforeCollection() - memoryPoolSummary.getOccupancyBeforeCollection(), getSizeBeforeCollection() - memoryPoolSummary.getSizeBeforeCollection(),
|
||||
getOccupancyAfterCollection() - memoryPoolSummary.getOccupancyAfterCollection(), getSizeAfterCollection() - memoryPoolSummary.getSizeAfterCollection());
|
||||
}
|
||||
|
||||
public MemoryPoolSummary add(MemoryPoolSummary memoryPoolSummary) {
|
||||
return new MemoryPoolSummary(
|
||||
getOccupancyBeforeCollection() + memoryPoolSummary.getOccupancyBeforeCollection(),
|
||||
getSizeBeforeCollection() + memoryPoolSummary.getSizeBeforeCollection(),
|
||||
getOccupancyAfterCollection() + memoryPoolSummary.getOccupancyAfterCollection(),
|
||||
getSizeAfterCollection() + memoryPoolSummary.getSizeAfterCollection());
|
||||
}
|
||||
|
||||
public long kBytesRecovered() {
|
||||
long kBytesRecovered = kByteDelta();
|
||||
return (kBytesRecovered > 0) ? kBytesRecovered : 0L;
|
||||
}
|
||||
|
||||
public long kBytesAllocated(MemoryPoolSummary previousHeapState) {
|
||||
long kBytesAllocated = occupancyBeforeCollection - previousHeapState.getOccupancyAfterCollection();
|
||||
return (kBytesAllocated > 0) ? kBytesAllocated : 0L;
|
||||
}
|
||||
|
||||
// Will be positive if data is copied into the pool and negative if the pool has been GC'ed
|
||||
public long kByteDelta() {
|
||||
return occupancyBeforeCollection - occupancyAfterCollection;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return sizeAfterCollection != -1;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return occupancyBeforeCollection + "K(" + sizeBeforeCollection + "K)->" + occupancyAfterCollection + "K(" + sizeAfterCollection + "K)";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event;
|
||||
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
/**
|
||||
* Exemplar
|
||||
* 11906.844: [GC pause (young)11906.881: [SoftReference, 0 refs, 0.0000060 secs]11906.881: [WeakReference, 0 refs, 0.0000020 secs]11906.881: [FinalReference, 0 refs, 0.0000010 secs]11906.881: [PhantomReference, 0 refs, 0.0000020 secs]11906.881: [JNI Weak Reference, 0.0002710 secs], 0.03831600 secs]
|
||||
*/
|
||||
public class ReferenceGCSummary {
|
||||
|
||||
private DateTimeStamp softReferenceDateTimeStamp;
|
||||
private int softReferenceCount;
|
||||
private double softReferencePauseTime;
|
||||
|
||||
private DateTimeStamp weakReferenceDateTimeStamp;
|
||||
private int weakReferenceCount;
|
||||
private double weakReferencePauseTime;
|
||||
|
||||
private DateTimeStamp finalReferenceDateTimeStamp;
|
||||
private int finalReferenceCount;
|
||||
private double finalReferencePauseTime;
|
||||
|
||||
private DateTimeStamp phantomReferenceDateTimeStamp;
|
||||
private int phantomReferenceCount;
|
||||
private int phantomReferenceFreedCount;
|
||||
private double phantomReferencePauseTime;
|
||||
|
||||
private DateTimeStamp jniWeakReferenceDateTimeStamp;
|
||||
private int jniWeakReferenceCount;
|
||||
private double jniWeakReferencePauseTime;
|
||||
|
||||
public ReferenceGCSummary() {
|
||||
}
|
||||
|
||||
public DateTimeStamp getSoftReferenceDateTimeStamp() {
|
||||
return softReferenceDateTimeStamp;
|
||||
}
|
||||
|
||||
public int getSoftReferenceCount() {
|
||||
return softReferenceCount;
|
||||
}
|
||||
|
||||
public double getSoftReferencePauseTime() {
|
||||
return softReferencePauseTime;
|
||||
}
|
||||
|
||||
public DateTimeStamp getWeakReferenceDateTimeStamp() {
|
||||
return weakReferenceDateTimeStamp;
|
||||
}
|
||||
|
||||
public int getWeakReferenceCount() {
|
||||
return weakReferenceCount;
|
||||
}
|
||||
|
||||
public double getWeakReferencePauseTime() {
|
||||
return weakReferencePauseTime;
|
||||
}
|
||||
|
||||
public DateTimeStamp getFinalReferenceDateTimeStamp() {
|
||||
return finalReferenceDateTimeStamp;
|
||||
}
|
||||
|
||||
public int getFinalReferenceCount() {
|
||||
return finalReferenceCount;
|
||||
}
|
||||
|
||||
public double getFinalReferencePauseTime() {
|
||||
return finalReferencePauseTime;
|
||||
}
|
||||
|
||||
public DateTimeStamp getPhantomReferenceDateTimeStamp() {
|
||||
return phantomReferenceDateTimeStamp;
|
||||
}
|
||||
|
||||
public int getPhantomReferenceCount() {
|
||||
return phantomReferenceCount;
|
||||
}
|
||||
|
||||
public int getPhantomReferenceFreedCount() {
|
||||
return phantomReferenceFreedCount;
|
||||
}
|
||||
|
||||
public double getPhantomReferencePauseTime() {
|
||||
return phantomReferencePauseTime;
|
||||
}
|
||||
|
||||
public DateTimeStamp getJniWeakReferenceDateTimeStamp() {
|
||||
return jniWeakReferenceDateTimeStamp;
|
||||
}
|
||||
|
||||
public double getJniWeakReferencePauseTime() {
|
||||
return jniWeakReferencePauseTime;
|
||||
}
|
||||
|
||||
public int getJniWeakReferenceCount() {
|
||||
return jniWeakReferenceCount;
|
||||
}
|
||||
|
||||
public void addSoftReferences(DateTimeStamp dateTimeStamp, int count, double pauseTime) {
|
||||
softReferenceDateTimeStamp = dateTimeStamp;
|
||||
softReferenceCount = count;
|
||||
softReferencePauseTime = pauseTime;
|
||||
}
|
||||
|
||||
public void addWeakReferences(DateTimeStamp dateTimeStamp, int count, double pauseTime) {
|
||||
weakReferenceDateTimeStamp = dateTimeStamp;
|
||||
weakReferenceCount = count;
|
||||
weakReferencePauseTime = pauseTime;
|
||||
}
|
||||
|
||||
public void addFinalReferences(DateTimeStamp dateTimeStamp, int count, double pauseTime) {
|
||||
finalReferenceDateTimeStamp = dateTimeStamp;
|
||||
finalReferenceCount = count;
|
||||
finalReferencePauseTime = pauseTime;
|
||||
}
|
||||
|
||||
public void addPhantomReferences(DateTimeStamp dateTimeStamp, int count, int freed, double pauseTime) {
|
||||
phantomReferenceDateTimeStamp = dateTimeStamp;
|
||||
phantomReferenceCount = count;
|
||||
phantomReferenceFreedCount = freed;
|
||||
phantomReferencePauseTime = pauseTime;
|
||||
}
|
||||
|
||||
public void addPhantomReferences(DateTimeStamp dateTimeStamp, int count, double pauseTime) {
|
||||
addPhantomReferences(dateTimeStamp, count, 0, pauseTime);
|
||||
}
|
||||
|
||||
public void addJNIWeakReferences(DateTimeStamp dateTimeStamp, double pauseTime) {
|
||||
jniWeakReferenceDateTimeStamp = dateTimeStamp;
|
||||
jniWeakReferenceCount = -1;
|
||||
jniWeakReferencePauseTime = pauseTime;
|
||||
}
|
||||
|
||||
public void addJNIWeakReferences(DateTimeStamp dateTimeStamp, int count, double pauseTime) {
|
||||
jniWeakReferenceDateTimeStamp = dateTimeStamp;
|
||||
jniWeakReferenceCount = count;
|
||||
jniWeakReferencePauseTime = pauseTime;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event;
|
||||
|
||||
public class RegionSummary {
|
||||
|
||||
private int before;
|
||||
private int after;
|
||||
private int assigned;
|
||||
|
||||
public RegionSummary(int before, int after, int assigned) {
|
||||
this.before = before;
|
||||
this.after = after;
|
||||
this.assigned = assigned;
|
||||
}
|
||||
|
||||
public int getBefore() {
|
||||
return this.before;
|
||||
}
|
||||
|
||||
public int getAfter() {
|
||||
return this.after;
|
||||
}
|
||||
|
||||
public int getAssigned() {
|
||||
return this.assigned;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event;
|
||||
|
||||
public class StatisticalSummary {
|
||||
|
||||
final static public double UNDEFINED = -1.0d;
|
||||
|
||||
private final double min;
|
||||
private final double average;
|
||||
private final double max;
|
||||
private final double diff;
|
||||
private final double sum;
|
||||
|
||||
public StatisticalSummary(double min, double average, double max, double diff, double sum) {
|
||||
this.min = min;
|
||||
this.average = average;
|
||||
this.max = max;
|
||||
this.diff = diff;
|
||||
this.sum = sum;
|
||||
}
|
||||
|
||||
public double getMin() {
|
||||
return min;
|
||||
}
|
||||
|
||||
public double getAverage() {
|
||||
return average;
|
||||
}
|
||||
|
||||
public double getMax() {
|
||||
return max;
|
||||
}
|
||||
|
||||
public double getDiff() {
|
||||
return diff;
|
||||
}
|
||||
|
||||
public double getSum() {
|
||||
return sum;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event;
|
||||
|
||||
public class SurvivorMemoryPoolSummary {
|
||||
|
||||
private final long occupancyBeforeCollection;
|
||||
private final long occupancyAfterCollection;
|
||||
private final long size;
|
||||
|
||||
public SurvivorMemoryPoolSummary(long occupancyBeforeCollection, long occupancyAfterCollection) {
|
||||
this.occupancyBeforeCollection = occupancyBeforeCollection;
|
||||
this.occupancyAfterCollection = occupancyAfterCollection;
|
||||
this.size = -1L;
|
||||
}
|
||||
|
||||
public SurvivorMemoryPoolSummary(long occupancyBeforeCollection, long occupancyAfterCollection, long sizeAfterCollection) {
|
||||
this.occupancyBeforeCollection = occupancyBeforeCollection;
|
||||
this.occupancyAfterCollection = occupancyAfterCollection;
|
||||
this.size = sizeAfterCollection;
|
||||
}
|
||||
|
||||
public long getOccupancyBeforeCollection() {
|
||||
return this.occupancyBeforeCollection;
|
||||
}
|
||||
|
||||
public long getOccupancyAfterCollection() {
|
||||
return this.occupancyAfterCollection;
|
||||
}
|
||||
|
||||
public long getSize() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class TLABSummary {
|
||||
|
||||
ArrayList<String> tlabRecords;
|
||||
|
||||
public TLABSummary() {
|
||||
}
|
||||
|
||||
public void add(String record) {
|
||||
tlabRecords.add(record);
|
||||
}
|
||||
|
||||
public void addTLABRecord() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//TLAB: gc thread: 0x00007f2f6424f000 [id: 27358] desired_size: 1024KB slow allocs: 0 refill waste: 16384B alloc: 0.00091 3061KB refills: 1 waste 99.6% gc: 1043864B slow: 0B fast: 0B
|
||||
//TLAB totals: thrds: 60 refills: 3222 max: 1397 slow allocs: 55 max 35 waste: 1.5% gc: 42509088B max: 1048360B slow: 9613800B max: 4478816B fast: 0B max: 0B
|
|
@ -0,0 +1,49 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event;
|
||||
|
||||
public class UnifiedCountSummary {
|
||||
|
||||
//Min: 1, Avg: 17.4, Max: 34, Diff: 33, Sum: 139, Workers: 8
|
||||
|
||||
private int min;
|
||||
private double average;
|
||||
private int max;
|
||||
private int diff;
|
||||
private int sum;
|
||||
private int threads;
|
||||
|
||||
public UnifiedCountSummary(int min, double average, int max, int diff, int sum, int threads) {
|
||||
this.min = min;
|
||||
this.average = average;
|
||||
this.max = max;
|
||||
this.diff = diff;
|
||||
this.sum = sum;
|
||||
this.threads = threads;
|
||||
}
|
||||
|
||||
public int getMin() {
|
||||
return min;
|
||||
}
|
||||
|
||||
public double getAverage() {
|
||||
return average;
|
||||
}
|
||||
|
||||
public int getMax() {
|
||||
return max;
|
||||
}
|
||||
|
||||
public int getDiff() {
|
||||
return diff;
|
||||
}
|
||||
|
||||
public int getSum() {
|
||||
return sum;
|
||||
}
|
||||
|
||||
public int getThreads() {
|
||||
return this.threads;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event;
|
||||
|
||||
public class UnifiedStatisticalSummary extends StatisticalSummary {
|
||||
|
||||
private int threads;
|
||||
|
||||
public UnifiedStatisticalSummary(double min, double average, double max, double diff, double sum, int threads) {
|
||||
super(min, average, max, diff, sum);
|
||||
this.threads = threads;
|
||||
}
|
||||
|
||||
public int getThreads() {
|
||||
return this.threads;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.g1gc;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
public class ConcurrentCleanupForNextMark extends G1GCConcurrentEvent {
|
||||
|
||||
public ConcurrentCleanupForNextMark(DateTimeStamp timeStamp, double duration) {
|
||||
super(timeStamp, GarbageCollectionTypes.ConcurrentCleanupForNextMark, GCCause.UNKNOWN_GCCAUSE, duration);
|
||||
}
|
||||
|
||||
public ConcurrentCleanupForNextMark(DateTimeStamp timeStamp, GCCause cause, double duration) {
|
||||
super(timeStamp, GarbageCollectionTypes.ConcurrentCleanupForNextMark, cause, duration);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.g1gc;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
public class ConcurrentClearClaimedMarks extends G1GCConcurrentEvent {
|
||||
|
||||
public ConcurrentClearClaimedMarks(DateTimeStamp timeStamp, double duration) {
|
||||
super(timeStamp, GarbageCollectionTypes.ConcurrentClearClaimedMarks, GCCause.UNKNOWN_GCCAUSE, duration);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.g1gc;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
public class ConcurrentCompleteCleanup extends G1GCConcurrentEvent {
|
||||
|
||||
public ConcurrentCompleteCleanup(DateTimeStamp timeStamp, double duration) {
|
||||
super(timeStamp, GarbageCollectionTypes.ConcurrentCompleteCleanup, GCCause.UNKNOWN_GCCAUSE, duration);
|
||||
}
|
||||
|
||||
public ConcurrentCompleteCleanup(DateTimeStamp timeStamp, GCCause cause, double duration) {
|
||||
super(timeStamp, GarbageCollectionTypes.ConcurrentCompleteCleanup, cause, duration);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.g1gc;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
public class ConcurrentCreateLiveData extends G1GCConcurrentEvent {
|
||||
|
||||
public ConcurrentCreateLiveData(DateTimeStamp timeStamp, double duration) {
|
||||
super(timeStamp, GarbageCollectionTypes.ConcurrentCreateLiveData, GCCause.UNKNOWN_GCCAUSE, duration);
|
||||
}
|
||||
|
||||
public ConcurrentCreateLiveData(DateTimeStamp timeStamp, GCCause cause, double duration) {
|
||||
super(timeStamp, GarbageCollectionTypes.ConcurrentCreateLiveData, cause, duration);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.g1gc;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
public class ConcurrentScanRootRegion extends G1GCConcurrentEvent {
|
||||
|
||||
public ConcurrentScanRootRegion(DateTimeStamp timeStamp, double duration) {
|
||||
super(timeStamp, GarbageCollectionTypes.ConcurrentRootRegionScan, GCCause.UNKNOWN_GCCAUSE, duration);
|
||||
}
|
||||
|
||||
public ConcurrentScanRootRegion(DateTimeStamp timeStamp, GCCause cause, double duration) {
|
||||
super(timeStamp, GarbageCollectionTypes.ConcurrentRootRegionScan, cause, duration);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.g1gc;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
|
||||
public class G1Cleanup extends G1RealPause {
|
||||
|
||||
public G1Cleanup(DateTimeStamp timeStamp, double duration) {
|
||||
super(timeStamp, GarbageCollectionTypes.G1GCCleanup, GCCause.GCCAUSE_NOT_SET, duration);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.g1gc;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
|
||||
public class G1ConcurrentCleanup extends G1GCConcurrentEvent {
|
||||
|
||||
public G1ConcurrentCleanup(DateTimeStamp timeStamp, double duration) {
|
||||
super(timeStamp, GarbageCollectionTypes.G1GCConcurrentCleanup, GCCause.GCCAUSE_NOT_SET, duration);
|
||||
}
|
||||
|
||||
public G1ConcurrentCleanup(DateTimeStamp timeStamp, GCCause cause, double duration) {
|
||||
super(timeStamp, GarbageCollectionTypes.G1GCConcurrentCleanup, cause, duration);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.g1gc;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class G1ConcurrentMark extends G1GCConcurrentEvent {
|
||||
|
||||
private double markFromRootsDuration = -1.0d;
|
||||
private int activeWorkerThreads = -1;
|
||||
private int availableWorkerThreads = -1;
|
||||
private double precleanDuration = -1.0d;
|
||||
private boolean aborted = false;
|
||||
|
||||
public G1ConcurrentMark(DateTimeStamp timeStamp, double duration) {
|
||||
super(timeStamp, GarbageCollectionTypes.ConcurrentMark, GCCause.GCCAUSE_NOT_SET, duration);
|
||||
}
|
||||
|
||||
public G1ConcurrentMark(DateTimeStamp timeStamp, GCCause cause, double duration) {
|
||||
super(timeStamp, GarbageCollectionTypes.G1GCConcurrentMark, cause, duration);
|
||||
}
|
||||
|
||||
public void setMarkFromRootsDuration(double duration) {
|
||||
this.markFromRootsDuration = duration;
|
||||
}
|
||||
|
||||
public double getMarkFromRootsDuration() {
|
||||
return markFromRootsDuration;
|
||||
}
|
||||
|
||||
public int getActiveWorkerThreads() {
|
||||
return activeWorkerThreads;
|
||||
}
|
||||
|
||||
public void setActiveWorkerThreads(int activeWorkerThreads) {
|
||||
this.activeWorkerThreads = activeWorkerThreads;
|
||||
}
|
||||
|
||||
public int getAvailableWorkerThreads() {
|
||||
return availableWorkerThreads;
|
||||
}
|
||||
|
||||
public void setAvailableWorkerThreads(int availableWorkerThreads) {
|
||||
this.availableWorkerThreads = availableWorkerThreads;
|
||||
}
|
||||
|
||||
public double getPrecleanDuration() {
|
||||
return precleanDuration;
|
||||
}
|
||||
|
||||
public void setPrecleanDuration(double duration) {
|
||||
this.precleanDuration = duration;
|
||||
}
|
||||
|
||||
public void abort() {
|
||||
this.aborted = true;
|
||||
}
|
||||
|
||||
public boolean isAborted() {
|
||||
return this.aborted;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.g1gc;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class G1ConcurrentMarkResetForOverflow extends G1GCConcurrentEvent {
|
||||
|
||||
public G1ConcurrentMarkResetForOverflow(DateTimeStamp timeStamp) {
|
||||
super(timeStamp, GarbageCollectionTypes.G1ConcurrentMarkResetForOverflow, GCCause.CONCURRENT_MARK_STACK_OVERFLOW, 0.0d);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.g1gc;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
|
||||
public class G1ConcurrentRebuildRememberedSets extends G1GCConcurrentEvent {
|
||||
|
||||
public G1ConcurrentRebuildRememberedSets(DateTimeStamp timeStamp, double duration) {
|
||||
super(timeStamp, GarbageCollectionTypes.G1GCConcurrentCleanup, GCCause.GCCAUSE_NOT_SET, duration);
|
||||
}
|
||||
|
||||
public G1ConcurrentRebuildRememberedSets(DateTimeStamp timeStamp, GCCause cause, double duration) {
|
||||
super(timeStamp, GarbageCollectionTypes.G1GCConcurrentCleanup, cause, duration);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.g1gc;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
/**
|
||||
* 2015-10-17T21:10:23.673-0400: 3993.137: [GC concurrent-string-deduplication, 79.3K->792.0B(78.6K), avg 96.2%, 0.0024351 secs]
|
||||
*/
|
||||
|
||||
public class G1ConcurrentStringDeduplication extends G1GCConcurrentEvent {
|
||||
|
||||
double startingStringVolume;
|
||||
double endingStringVolume;
|
||||
double reduction;
|
||||
double percentReduction;
|
||||
|
||||
public G1ConcurrentStringDeduplication(DateTimeStamp timeStamp, double startingStringVolume, double endingStringVolume, double reduction, double percentReduction, double duration) {
|
||||
this(timeStamp, GCCause.GCCAUSE_NOT_SET, startingStringVolume, endingStringVolume, reduction, percentReduction, duration);
|
||||
}
|
||||
|
||||
public G1ConcurrentStringDeduplication(DateTimeStamp timeStamp, GCCause cause, double startingStringVolume, double endingStringVolume, double reduction, double percentReduction, double duration) {
|
||||
super(timeStamp, GarbageCollectionTypes.ConcurrentStringDeduplication, cause, duration);
|
||||
this.startingStringVolume = startingStringVolume;
|
||||
this.endingStringVolume = endingStringVolume;
|
||||
this.reduction = reduction;
|
||||
this.percentReduction = percentReduction;
|
||||
}
|
||||
|
||||
public double getStartingStringVolume() {
|
||||
return startingStringVolume;
|
||||
}
|
||||
|
||||
public double getEndingStringVolume() {
|
||||
return endingStringVolume;
|
||||
}
|
||||
|
||||
public double getReduction() {
|
||||
return reduction;
|
||||
}
|
||||
|
||||
public double getPercentReduction() {
|
||||
return percentReduction;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.g1gc;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class G1FullGC extends G1RealPause {
|
||||
|
||||
HashMap<String, Double> internalPhaseTimes = new HashMap<>();
|
||||
|
||||
public G1FullGC(DateTimeStamp timeStamp, GCCause cause, double pauseTime) {
|
||||
this(timeStamp, GarbageCollectionTypes.Full, cause, pauseTime);
|
||||
}
|
||||
|
||||
public G1FullGC(DateTimeStamp timeStamp, GarbageCollectionTypes type, GCCause cause, double pauseTime) {
|
||||
super(timeStamp, type, cause, pauseTime);
|
||||
}
|
||||
|
||||
public boolean isFull() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void addInternalPhase(String internalPhase, Double duration) {
|
||||
internalPhaseTimes.put(internalPhase, duration);
|
||||
}
|
||||
|
||||
public Stream<String> internalPhases() {
|
||||
return internalPhaseTimes.keySet().stream();
|
||||
}
|
||||
|
||||
public double internalPhaseDuration(String phaseName) {
|
||||
return internalPhaseTimes.get(phaseName);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.g1gc;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
/**
|
||||
* full GC not elsewhere specified on the G1 garbage collector
|
||||
*/
|
||||
public class G1FullGCNES extends G1FullGC {
|
||||
public G1FullGCNES(DateTimeStamp timeStamp, GCCause cause, double pauseTime) {
|
||||
this(timeStamp, GarbageCollectionTypes.Full, cause, pauseTime);
|
||||
}
|
||||
|
||||
public G1FullGCNES(DateTimeStamp timeStamp, GarbageCollectionTypes type, GCCause cause, double pauseTime) {
|
||||
super(timeStamp, type, cause, pauseTime);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.g1gc;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
abstract public class G1GCConcurrentEvent extends G1GCEvent {
|
||||
|
||||
public G1GCConcurrentEvent(DateTimeStamp timeStamp, GarbageCollectionTypes type, GCCause cause, double duration) {
|
||||
super(timeStamp, type, cause, duration);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.g1gc;
|
||||
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GCEvent;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
abstract public class G1GCEvent extends GCEvent {
|
||||
|
||||
public G1GCEvent(DateTimeStamp timeStamp, GarbageCollectionTypes type, GCCause cause, double duration) {
|
||||
super(timeStamp, type, cause, duration);
|
||||
}
|
||||
|
||||
public G1GCEvent(DateTimeStamp timeStamp, double duration) {
|
||||
this(timeStamp, GarbageCollectionTypes.Unknown, GCCause.UNKNOWN_GCCAUSE, duration);
|
||||
}
|
||||
|
||||
|
||||
public G1GCEvent(DateTimeStamp timeStamp, GCCause cause, double duration) {
|
||||
this(timeStamp, GarbageCollectionTypes.Unknown, cause, duration);
|
||||
}
|
||||
|
||||
public G1GCEvent(DateTimeStamp timeStamp, GarbageCollectionTypes gcType, double duration) {
|
||||
this(timeStamp, gcType, GCCause.UNKNOWN_GCCAUSE, duration);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.g1gc;
|
||||
|
||||
import com.microsoft.censum.event.CPUSummary;
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.event.MemoryPoolSummary;
|
||||
import com.microsoft.censum.event.ReferenceGCSummary;
|
||||
import com.microsoft.censum.event.SurvivorMemoryPoolSummary;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public abstract class G1GCPauseEvent extends G1GCEvent {
|
||||
|
||||
private MemoryPoolSummary NULL_POOL = new MemoryPoolSummary(-1L, -1L, -1L, -1L);
|
||||
|
||||
MemoryPoolSummary eden;
|
||||
SurvivorMemoryPoolSummary survivor;
|
||||
MemoryPoolSummary heap;
|
||||
MemoryPoolSummary permOrMetaspace;
|
||||
ReferenceGCSummary referenceGCSummary = null;
|
||||
|
||||
CPUSummary cpuSummary;
|
||||
|
||||
public G1GCPauseEvent(DateTimeStamp timeStamp, GarbageCollectionTypes type, GCCause cause, double duration) {
|
||||
super(timeStamp, type, cause, duration);
|
||||
}
|
||||
|
||||
public void addMemorySummary(MemoryPoolSummary eden, SurvivorMemoryPoolSummary survivor, MemoryPoolSummary heap) {
|
||||
this.eden = eden;
|
||||
this.survivor = survivor;
|
||||
this.heap = heap;
|
||||
}
|
||||
|
||||
public void addMemorySummary(MemoryPoolSummary heap) {
|
||||
this.addMemorySummary(null, null, heap);
|
||||
}
|
||||
|
||||
public void addPermOrMetaSpaceRecord(MemoryPoolSummary permOrMetaspaceRecord) {
|
||||
permOrMetaspace = permOrMetaspaceRecord;
|
||||
}
|
||||
|
||||
public void addCPUSummary(CPUSummary summary) {
|
||||
this.cpuSummary = summary;
|
||||
}
|
||||
|
||||
public MemoryPoolSummary getEden() {
|
||||
return this.eden;
|
||||
}
|
||||
|
||||
public SurvivorMemoryPoolSummary getSurvivor() {
|
||||
return this.survivor;
|
||||
}
|
||||
|
||||
public MemoryPoolSummary getHeap() {
|
||||
return this.heap;
|
||||
}
|
||||
|
||||
public MemoryPoolSummary getPermOrMetaspace() {
|
||||
return this.permOrMetaspace;
|
||||
}
|
||||
|
||||
public MemoryPoolSummary getTenured() {
|
||||
if ((getEden() == null) || (getHeap() == null)) {
|
||||
return NULL_POOL;
|
||||
} else if (getSurvivor() == null) {
|
||||
return new MemoryPoolSummary(getHeap().getOccupancyBeforeCollection() - this.getEden().getOccupancyBeforeCollection(),
|
||||
getHeap().getSizeBeforeCollection() - getEden().getSizeBeforeCollection(),
|
||||
getHeap().getOccupancyAfterCollection() - getEden().getOccupancyAfterCollection(),
|
||||
getHeap().getSizeAfterCollection() - getEden().getSizeAfterCollection());
|
||||
} else {
|
||||
return new MemoryPoolSummary(getHeap().getOccupancyBeforeCollection() - this.getEden().getOccupancyBeforeCollection(),
|
||||
getHeap().getSizeBeforeCollection() - getEden().getSizeBeforeCollection() - getSurvivor().getOccupancyBeforeCollection(),
|
||||
getHeap().getOccupancyAfterCollection() - getEden().getOccupancyAfterCollection() - getSurvivor().getOccupancyAfterCollection(),
|
||||
getHeap().getSizeAfterCollection() - getEden().getSizeAfterCollection());
|
||||
}
|
||||
}
|
||||
|
||||
public void add(ReferenceGCSummary summary) {
|
||||
this.referenceGCSummary = summary;
|
||||
}
|
||||
|
||||
public ReferenceGCSummary getReferenceGCSummary() {
|
||||
return this.referenceGCSummary;
|
||||
}
|
||||
|
||||
public CPUSummary getCpuSummary() {
|
||||
return this.cpuSummary;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.g1gc;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
|
||||
public class G1Mixed extends G1Young {
|
||||
|
||||
public G1Mixed(DateTimeStamp dateTimeStamp, GCCause gcCause, double pauseTime) {
|
||||
super(dateTimeStamp, GarbageCollectionTypes.Mixed, gcCause, pauseTime);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.g1gc;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
/**
|
||||
* not a trap
|
||||
*/
|
||||
public abstract class G1RealPause extends G1GCPauseEvent {
|
||||
public G1RealPause(DateTimeStamp timeStamp, GarbageCollectionTypes type, GCCause cause, double duration) {
|
||||
super(timeStamp, type, cause, duration);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.g1gc;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
|
||||
public class G1Remark extends G1RealPause {
|
||||
|
||||
private double referenceProcessingTime = 0.0d;
|
||||
private double finalizeMarkingTime = 0.0d;
|
||||
private double unloadingTime = 0.0d;
|
||||
|
||||
public G1Remark(DateTimeStamp timeStamp, double referenceProcessingTimes, double duration) {
|
||||
super(timeStamp, GarbageCollectionTypes.G1GCRemark, GCCause.UNKNOWN_GCCAUSE, duration);
|
||||
this.referenceProcessingTime = referenceProcessingTimes;
|
||||
}
|
||||
|
||||
public G1Remark(DateTimeStamp timeStamp, double referenceProcessingTimes, double finalizeMarking, double unloading, double duration) {
|
||||
this(timeStamp, referenceProcessingTimes, duration);
|
||||
this.finalizeMarkingTime = finalizeMarking;
|
||||
this.unloadingTime = unloading;
|
||||
}
|
||||
|
||||
public double getReferenceProcessingTime() {
|
||||
return this.referenceProcessingTime;
|
||||
}
|
||||
|
||||
public double getFinalizeMarkingTime() {
|
||||
return this.finalizeMarkingTime;
|
||||
}
|
||||
|
||||
public double getUnloadingTime() {
|
||||
return this.unloadingTime;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.g1gc;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class G1SystemGC extends G1FullGC {
|
||||
|
||||
public G1SystemGC(DateTimeStamp timeStamp, double pauseTime) {
|
||||
super(timeStamp, GarbageCollectionTypes.SystemGC, GCCause.JAVA_LANG_SYSTEM, pauseTime);
|
||||
}
|
||||
|
||||
public boolean isFull() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isSystemGC() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.g1gc;
|
||||
|
||||
import com.microsoft.censum.aggregator.Aggregator;
|
||||
import com.microsoft.censum.event.CPUSummary;
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.event.MemoryPoolSummary;
|
||||
import com.microsoft.censum.event.SurvivorMemoryPoolSummary;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* G1 Event to capture parser errors
|
||||
*/
|
||||
|
||||
public class G1Trap extends G1GCPauseEvent {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(G1Trap.class.getName());
|
||||
|
||||
private String message = "Internal EventSource Error @ ";
|
||||
|
||||
public G1Trap() {
|
||||
super(new DateTimeStamp(0.0d), GarbageCollectionTypes.G1Trap, GCCause.UNKNOWN_GCCAUSE, 0.0d);
|
||||
}
|
||||
|
||||
int errorCount = 0;
|
||||
|
||||
private void trap(Exception e) {
|
||||
if (errorCount > 100) return;
|
||||
errorCount++;
|
||||
LOGGER.log(Level.INFO, message + super.getDateTimeStamp().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DateTimeStamp getDateTimeStamp() {
|
||||
trap(new Exception());
|
||||
return super.getDateTimeStamp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDuration() {
|
||||
trap(new Exception());
|
||||
return super.getDuration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GCTrap: " + super.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGCCause(GCCause cause) {
|
||||
trap(new Exception());
|
||||
}
|
||||
|
||||
@Override
|
||||
public GCCause getGCCause() {
|
||||
trap(new Exception());
|
||||
return super.getGCCause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GarbageCollectionTypes getGarbageCollectionType() {
|
||||
trap(new Exception());
|
||||
return super.getGarbageCollectionType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isYoung() {
|
||||
trap(new Exception());
|
||||
return super.isYoung();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFull() {
|
||||
trap(new Exception());
|
||||
return super.isFull();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConcurrent() {
|
||||
trap(new Exception());
|
||||
return super.isConcurrent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isG1Young() {
|
||||
trap(new Exception());
|
||||
return super.isG1Young();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isG1Mixed() {
|
||||
trap(new Exception());
|
||||
return super.isG1Mixed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isG1Concurrent() {
|
||||
trap(new Exception());
|
||||
return super.isG1Concurrent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSystemGC() {
|
||||
trap(new Exception());
|
||||
return super.isSystemGC();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMemorySummary(MemoryPoolSummary eden, SurvivorMemoryPoolSummary survivor, MemoryPoolSummary heap) {
|
||||
trap(new Exception());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCPUSummary(CPUSummary summary) {
|
||||
trap(new Exception());
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemoryPoolSummary getEden() {
|
||||
trap(new Exception());
|
||||
return super.getEden();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SurvivorMemoryPoolSummary getSurvivor() {
|
||||
trap(new Exception());
|
||||
return super.getSurvivor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemoryPoolSummary getHeap() {
|
||||
trap(new Exception());
|
||||
return super.getHeap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CPUSummary getCpuSummary() {
|
||||
trap(new Exception());
|
||||
return super.getCpuSummary();
|
||||
}
|
||||
|
||||
|
||||
public void addCPUSummary() {
|
||||
trap(new Exception());
|
||||
}
|
||||
|
||||
public void execute(Aggregator aggregator) {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,255 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.g1gc;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.event.StatisticalSummary;
|
||||
import com.microsoft.censum.event.UnifiedStatisticalSummary;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
||||
public class G1Young extends G1RealPause {
|
||||
|
||||
private double parallelPhaseDuration = -1.0d;
|
||||
private int gcWorkers;
|
||||
private double codeRootFixupDuration = -1.0d;
|
||||
private double codeRootMigrationDuration = -1.0d;
|
||||
private double codeRootPurgeDuration = -1.0d;
|
||||
private double clearCTDuration = -1.0d;
|
||||
private double expandHeapDuration = -1.0d;
|
||||
private double stringDedupingDuration = -1.0d;
|
||||
private int stringDeduppingWorkers;
|
||||
private StatisticalSummary queueFixupStatistics;
|
||||
private StatisticalSummary tableFixupStatistics;
|
||||
private double otherPhaseDurations = -1.0d;
|
||||
private StatisticalSummary workersStart;
|
||||
private StatisticalSummary workersEnd;
|
||||
private StatisticalSummary workerOther;
|
||||
private StatisticalSummary workerTotal;
|
||||
private StatisticalSummary processedBuffersSummary;
|
||||
private boolean toSpaceExhausted = false;
|
||||
|
||||
private final HashMap<String, StatisticalSummary> parallelPhaseSummaries = new HashMap<String, StatisticalSummary>();
|
||||
private final HashMap<String, Double> phaseDurations = new HashMap<>();
|
||||
|
||||
public G1Young(DateTimeStamp dateTimeStamp, GarbageCollectionTypes gcType, GCCause gcCause, double pauseTime) {
|
||||
super(dateTimeStamp, gcType, gcCause, pauseTime);
|
||||
}
|
||||
|
||||
public G1Young(DateTimeStamp dateTimeStamp, GCCause gcCause, double pauseTime) {
|
||||
this(dateTimeStamp, GarbageCollectionTypes.Young, gcCause, pauseTime);
|
||||
}
|
||||
|
||||
public void toSpaceExhausted() {
|
||||
toSpaceExhausted = true;
|
||||
}
|
||||
|
||||
public boolean isToSpaceExhausted() {
|
||||
return toSpaceExhausted;
|
||||
}
|
||||
|
||||
public void setParallelPhaseDuration(double duration) {
|
||||
this.parallelPhaseDuration = duration;
|
||||
}
|
||||
|
||||
public void setGcWorkers(int count) {
|
||||
this.gcWorkers = count;
|
||||
}
|
||||
|
||||
public void setCodeRootFixupDuration(double duration) {
|
||||
this.codeRootFixupDuration = duration;
|
||||
}
|
||||
|
||||
public void setStringDedupingDuration(double duration, int workers) {
|
||||
this.stringDedupingDuration = duration;
|
||||
this.stringDeduppingWorkers = workers;
|
||||
}
|
||||
|
||||
public void setQueueFixupStatistics(StatisticalSummary summary) {
|
||||
this.queueFixupStatistics = summary;
|
||||
}
|
||||
|
||||
public void setTableFixupStatistics(StatisticalSummary summary) {
|
||||
this.tableFixupStatistics = summary;
|
||||
}
|
||||
|
||||
public void setCodeRootMigrationDuration(double duration) {
|
||||
this.codeRootMigrationDuration = duration;
|
||||
}
|
||||
|
||||
public void setCodeRootPurgeDuration(double duration) {
|
||||
this.codeRootPurgeDuration = duration;
|
||||
}
|
||||
|
||||
public void setClearCTDuration(double duration) {
|
||||
this.clearCTDuration = duration;
|
||||
}
|
||||
|
||||
public void setExpandHeapDuration(double duration) {
|
||||
this.expandHeapDuration = duration;
|
||||
}
|
||||
|
||||
public void setOtherPhaseDurations(double duration) {
|
||||
this.otherPhaseDurations = duration;
|
||||
}
|
||||
|
||||
public double getParallelPhaseDurationTime() {
|
||||
return this.parallelPhaseDuration;
|
||||
}
|
||||
|
||||
public int getGcWorkers() {
|
||||
return gcWorkers;
|
||||
}
|
||||
|
||||
public double getCodeRootFixupDuration() {
|
||||
return codeRootFixupDuration;
|
||||
}
|
||||
|
||||
public double getCodeRootMigrationDuration() {
|
||||
return codeRootMigrationDuration;
|
||||
}
|
||||
|
||||
public double getCodeRootPurgeDuration() {
|
||||
return codeRootPurgeDuration;
|
||||
}
|
||||
|
||||
public double getClearCTDuration() {
|
||||
return clearCTDuration;
|
||||
}
|
||||
|
||||
public double getExpandHeapDuration() {
|
||||
return this.expandHeapDuration;
|
||||
}
|
||||
|
||||
public double getStringDedupingDuration() {
|
||||
return this.stringDedupingDuration;
|
||||
}
|
||||
|
||||
public StatisticalSummary getQueueFixupStatistics() {
|
||||
return this.queueFixupStatistics;
|
||||
}
|
||||
|
||||
public StatisticalSummary getTableFixupStatistics() {
|
||||
return this.tableFixupStatistics;
|
||||
}
|
||||
|
||||
public double getOtherPhaseDurations() {
|
||||
return otherPhaseDurations;
|
||||
}
|
||||
|
||||
public void setWorkersStart(StatisticalSummary summary) {
|
||||
this.workersStart = summary;
|
||||
}
|
||||
|
||||
public StatisticalSummary getWorkersStart() {
|
||||
return this.workersStart;
|
||||
}
|
||||
|
||||
public void setWorkersEnd(StatisticalSummary summary) {
|
||||
this.workersEnd = summary;
|
||||
}
|
||||
|
||||
public StatisticalSummary getWorkersEnd() {
|
||||
return this.workersEnd;
|
||||
}
|
||||
|
||||
public void addProcessedBuffersSummary(StatisticalSummary summary) {
|
||||
this.processedBuffersSummary = summary;
|
||||
}
|
||||
|
||||
public StatisticalSummary getProcessedBuffersSummary() {
|
||||
return this.processedBuffersSummary;
|
||||
}
|
||||
|
||||
public void addWorkerActivity(String group, StatisticalSummary statisticalSummary) {
|
||||
if (group.endsWith("Other"))
|
||||
workerOther = statisticalSummary;
|
||||
if (group.endsWith("Total"))
|
||||
workerTotal = statisticalSummary;
|
||||
}
|
||||
|
||||
public StatisticalSummary getWorkerOther() {
|
||||
return this.workerOther;
|
||||
}
|
||||
|
||||
public StatisticalSummary getWorkerTotal() {
|
||||
return this.workerTotal;
|
||||
}
|
||||
|
||||
public void addPhaseDuration(String key, double duration) {
|
||||
phaseDurations.put(key, duration);
|
||||
}
|
||||
|
||||
public Iterator<String> phaseNames() {
|
||||
return phaseDurations.keySet().iterator();
|
||||
}
|
||||
|
||||
public double phaseDurationFor(String phaseName) {
|
||||
return phaseDurations.get(phaseName);
|
||||
}
|
||||
|
||||
public void addParallelPhaseSummary(String key, StatisticalSummary summary) {
|
||||
this.parallelPhaseSummaries.put(key, summary);
|
||||
}
|
||||
|
||||
public Iterator<String> parallelPhaseNames() {
|
||||
return parallelPhaseSummaries.keySet().iterator();
|
||||
}
|
||||
|
||||
public StatisticalSummary parallelPhaseSummaryFor(String phaseName) {
|
||||
return parallelPhaseSummaries.get(phaseName);
|
||||
}
|
||||
|
||||
public void queueFixupStatistics(StatisticalSummary summary) {
|
||||
this.queueFixupStatistics = summary;
|
||||
}
|
||||
|
||||
public void tableFixupStatistics(StatisticalSummary summary) {
|
||||
this.tableFixupStatistics = summary;
|
||||
}
|
||||
|
||||
private HashMap<String, Double> preEvacuateCSetPhase = new HashMap<>(3);
|
||||
private HashMap<String, UnifiedStatisticalSummary> evacuateCSetPhase = new HashMap<>();
|
||||
private HashMap<String, Double> postEvacuateCSetPhase = new HashMap<>();
|
||||
|
||||
public void addPreEvacuationCollectionPhase(String name, double duration) {
|
||||
preEvacuateCSetPhase.put(name, duration);
|
||||
}
|
||||
|
||||
public Stream<String> preEvacuateCSetPhaseNames() {
|
||||
return preEvacuateCSetPhase.keySet().stream();
|
||||
}
|
||||
|
||||
public double preEvacuateCSetPhaseDuration(String name) {
|
||||
return preEvacuateCSetPhase.get(name);
|
||||
}
|
||||
|
||||
public void addEvacuationCollectionPhase(String name, UnifiedStatisticalSummary summary) {
|
||||
evacuateCSetPhase.put(name, summary);
|
||||
}
|
||||
|
||||
public Stream<String> evacuateCSetPhaseNames() {
|
||||
return evacuateCSetPhase.keySet().stream();
|
||||
}
|
||||
|
||||
public StatisticalSummary evacuateCSetPhaseDuration(String name) {
|
||||
return evacuateCSetPhase.get(name);
|
||||
}
|
||||
|
||||
public void addPostEvacuationCollectionPhase(String name, double summary) {
|
||||
postEvacuateCSetPhase.put(name, summary);
|
||||
}
|
||||
|
||||
public Stream<String> postEvacuateCSetPhaseNames() {
|
||||
return postEvacuateCSetPhase.keySet().stream();
|
||||
}
|
||||
|
||||
public double postEvacuateCSetPhaseDuration(String name) {
|
||||
return postEvacuateCSetPhase.get(name);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.g1gc;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
|
||||
public class G1YoungInitialMark extends G1Young {
|
||||
|
||||
public G1YoungInitialMark(DateTimeStamp dateTimeStamp, GCCause gcCause, double pauseTime) {
|
||||
super(dateTimeStamp, GarbageCollectionTypes.G1GCYoungInitialMark, gcCause, pauseTime);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,445 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.g1gc;
|
||||
|
||||
|
||||
/*
|
||||
Recent concurrent refinement statistics
|
||||
Processed 4907 cards
|
||||
Of 32 completed buffers:
|
||||
32 ( 93.8%) by concurrent RS threads.
|
||||
2 ( 6.2%) by mutator threads.
|
||||
Did 0 coarsenings.
|
||||
Concurrent RS threads times (s)
|
||||
0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
|
||||
Concurrent sampling threads times (s)
|
||||
0.00
|
||||
|
||||
Current rem set statistics
|
||||
Total per region rem sets sizes = 230532K. Max = 1880K.
|
||||
105K ( 0.0%) by 2 Young regions
|
||||
39K ( 0.0%) by 4 Humonguous regions
|
||||
15506K ( 6.7%) by 1569 Free regions
|
||||
214881K ( 93.2%) by 985 Old regions
|
||||
Static structures = 600K, free_lists = 10371K.
|
||||
9617950 occupied cards represented.
|
||||
1515 ( 0.0%) entries by 2 Young regions
|
||||
4 ( 0.0%) entries by 4 Humonguous regions
|
||||
0 ( 0.0%) entries by 1569 Free regions
|
||||
9616431 (100.0%) entries by 985 Old regions
|
||||
Region with largest rem set = 0:(O)[0x00000002c0000000,0x00000002c0800000,0x00000002c0800000], size = 1880K, occupied = 1410K.
|
||||
Total heap region code root sets sizes = 171K. Max = 97K.
|
||||
0K ( 0.0%) by 2 Young regions
|
||||
0K ( 0.0%) by 4 Humonguous regions
|
||||
24K ( 14.3%) by 1569 Free regions
|
||||
147K ( 85.7%) by 985 Old regions
|
||||
5416 code roots represented.
|
||||
0 ( 0.0%) elements by 2 Young regions
|
||||
0 ( 0.0%) elements by 4 Humonguous regions
|
||||
0 ( 0.0%) elements by 1569 Free regions
|
||||
5416 (100.0%) elements by 985 Old regions
|
||||
Region with largest amount of code roots = 0:(O)[0x00000002c0000000,0x00000002c0800000,0x00000002c0800000], size = 97K, num_elems = 4.
|
||||
*/
|
||||
public class RSetConcurrentRefinement {
|
||||
|
||||
ConcurrentRefinementStatistics concurrentRefinementStatistics;
|
||||
private int totalPerRegionRSetSize;
|
||||
private int maxPerRegionRSetSize;
|
||||
|
||||
private RegionsSummary regionsRSetSizeAndCardCount;
|
||||
private int youngRegionRSetSize;
|
||||
private int youngRegionsRSetCardCount;
|
||||
private int humonguousRegionRSetSize;
|
||||
private int humonguousRegionsRSetCardCount;
|
||||
private int staticStructuresSize;
|
||||
private int freeListSize;
|
||||
private int occupiedCards;
|
||||
|
||||
private int entriesByYoungRegions;
|
||||
private int youngRegionCount;
|
||||
private int entriesByHumonguousRegions;
|
||||
private int humonguousRegionCount;
|
||||
private int entriesByFreeRegions;
|
||||
private int freeRegionsCount;
|
||||
private int entriesByOldRegions;
|
||||
private int oldRegionCount;
|
||||
private int largestRSetSize;
|
||||
private int largestRSetOccupancy;
|
||||
private int heapRegionCodeRootSetsSize;
|
||||
private int heapRegionCodeRootSetsMaxSize;
|
||||
private RegionsSummary regionCodeRootSizeAndRegions;
|
||||
private int codeRootsRepresented;
|
||||
private RegionsSummary elementsByRegionCounts;
|
||||
private int largestAmountOfCodeRootsSize;
|
||||
private int largestAmountOfCodeRootsNumberOfElements;
|
||||
|
||||
public RSetConcurrentRefinement() {
|
||||
}
|
||||
|
||||
public ConcurrentRefinementStatistics getConcurrentRefinementStatistics() {
|
||||
return this.concurrentRefinementStatistics;
|
||||
}
|
||||
|
||||
public void setConcurrentRefinementStatistics(ConcurrentRefinementStatistics statistics) {
|
||||
this.concurrentRefinementStatistics = statistics;
|
||||
}
|
||||
|
||||
public int getTotalPerRegionRSetSize() {
|
||||
return totalPerRegionRSetSize;
|
||||
}
|
||||
|
||||
public void setTotalPerRegionRSetSize(int totalPerRegionRSetSize) {
|
||||
this.totalPerRegionRSetSize = totalPerRegionRSetSize;
|
||||
}
|
||||
|
||||
public int getMaxPerRegionRSetSize() {
|
||||
return maxPerRegionRSetSize;
|
||||
}
|
||||
|
||||
public void setMaxPerRegionRSetSize(int maxPerRegionRSetSize) {
|
||||
this.maxPerRegionRSetSize = maxPerRegionRSetSize;
|
||||
}
|
||||
|
||||
public RegionsSummary getRegionsRSetSizeAndCardCount() {
|
||||
return regionsRSetSizeAndCardCount;
|
||||
}
|
||||
|
||||
public void setRegionsRSetSizeAndCardCount(RegionsSummary regionsRSetSizeAndCardCount) {
|
||||
this.regionsRSetSizeAndCardCount = regionsRSetSizeAndCardCount;
|
||||
}
|
||||
|
||||
public int getYoungRegionRSetSize() {
|
||||
return youngRegionRSetSize;
|
||||
}
|
||||
|
||||
public void setYoungRegionRSetSize(int youngRegionRSetSize) {
|
||||
this.youngRegionRSetSize = youngRegionRSetSize;
|
||||
}
|
||||
|
||||
public int getYoungRegionsRSetCardCount() {
|
||||
return youngRegionsRSetCardCount;
|
||||
}
|
||||
|
||||
public void setYoungRegionsRSetCardCount(int youngRegionsRSetCardCount) {
|
||||
this.youngRegionsRSetCardCount = youngRegionsRSetCardCount;
|
||||
}
|
||||
|
||||
public int getHumonguousRegionRSetSize() {
|
||||
return humonguousRegionRSetSize;
|
||||
}
|
||||
|
||||
public void setHumonguousRegionRSetSize(int humonguousRegionRSetSize) {
|
||||
this.humonguousRegionRSetSize = humonguousRegionRSetSize;
|
||||
}
|
||||
|
||||
public int getHumonguousRegionsRSetCardCount() {
|
||||
return humonguousRegionsRSetCardCount;
|
||||
}
|
||||
|
||||
public void setHumonguousRegionsRSetCardCount(int humonguousRegionsRSetCardCount) {
|
||||
this.humonguousRegionsRSetCardCount = humonguousRegionsRSetCardCount;
|
||||
}
|
||||
|
||||
public int getStaticStructuresSize() {
|
||||
return staticStructuresSize;
|
||||
}
|
||||
|
||||
public void setStaticStructuresSize(int staticStructuresSize) {
|
||||
this.staticStructuresSize = staticStructuresSize;
|
||||
}
|
||||
|
||||
public int getFreeListSize() {
|
||||
return freeListSize;
|
||||
}
|
||||
|
||||
public void setFreeListSize(int freeListSize) {
|
||||
this.freeListSize = freeListSize;
|
||||
}
|
||||
|
||||
public int getOccupiedCards() {
|
||||
return occupiedCards;
|
||||
}
|
||||
|
||||
public void setOccupiedCards(int occupiedCards) {
|
||||
this.occupiedCards = occupiedCards;
|
||||
}
|
||||
|
||||
public int getEntriesByYoungRegions() {
|
||||
return entriesByYoungRegions;
|
||||
}
|
||||
|
||||
public void setEntriesByYoungRegions(int entriesByYoungRegions) {
|
||||
this.entriesByYoungRegions = entriesByYoungRegions;
|
||||
}
|
||||
|
||||
public int getYoungRegionCount() {
|
||||
return youngRegionCount;
|
||||
}
|
||||
|
||||
public void setYoungRegionCount(int youngRegionCount) {
|
||||
this.youngRegionCount = youngRegionCount;
|
||||
}
|
||||
|
||||
public int getEntriesByHumonguousRegions() {
|
||||
return entriesByHumonguousRegions;
|
||||
}
|
||||
|
||||
public void setEntriesByHumonguousRegions(int entriesByHumonguousRegions) {
|
||||
this.entriesByHumonguousRegions = entriesByHumonguousRegions;
|
||||
}
|
||||
|
||||
public int getHumonguousRegionCount() {
|
||||
return humonguousRegionCount;
|
||||
}
|
||||
|
||||
public void setHumonguousRegionCount(int humonguousRegionCount) {
|
||||
this.humonguousRegionCount = humonguousRegionCount;
|
||||
}
|
||||
|
||||
public int getEntriesByFreeRegions() {
|
||||
return entriesByFreeRegions;
|
||||
}
|
||||
|
||||
public void setEntriesByFreeRegions(int entriesByFreeRegions) {
|
||||
this.entriesByFreeRegions = entriesByFreeRegions;
|
||||
}
|
||||
|
||||
public int getFreeRegionsCount() {
|
||||
return freeRegionsCount;
|
||||
}
|
||||
|
||||
public void setFreeRegionsCount(int freeRegionsCount) {
|
||||
this.freeRegionsCount = freeRegionsCount;
|
||||
}
|
||||
|
||||
public int getEntriesByOldRegions() {
|
||||
return entriesByOldRegions;
|
||||
}
|
||||
|
||||
public void setEntriesByOldRegions(int entriesByOldRegions) {
|
||||
this.entriesByOldRegions = entriesByOldRegions;
|
||||
}
|
||||
|
||||
public int getOldRegionCount() {
|
||||
return oldRegionCount;
|
||||
}
|
||||
|
||||
public void setOldRegionCount(int oldRegionCount) {
|
||||
this.oldRegionCount = oldRegionCount;
|
||||
}
|
||||
|
||||
public int getLargestRSetSize() {
|
||||
return largestRSetSize;
|
||||
}
|
||||
|
||||
public void setLargestRSetSize(int largestRSetSize) {
|
||||
this.largestRSetSize = largestRSetSize;
|
||||
}
|
||||
|
||||
public int getLargestRSetOccupancy() {
|
||||
return largestRSetOccupancy;
|
||||
}
|
||||
|
||||
public void setLargestRSetOccupancy(int largestRSetOccupancy) {
|
||||
this.largestRSetOccupancy = largestRSetOccupancy;
|
||||
}
|
||||
|
||||
public int getHeapRegionCodeRootSetsSize() {
|
||||
return heapRegionCodeRootSetsSize;
|
||||
}
|
||||
|
||||
public void setHeapRegionCodeRootSetsSize(int heapRegionCodeRootSetsSize) {
|
||||
this.heapRegionCodeRootSetsSize = heapRegionCodeRootSetsSize;
|
||||
}
|
||||
|
||||
public int getHeapRegionCodeRootSetsMaxSize() {
|
||||
return heapRegionCodeRootSetsMaxSize;
|
||||
}
|
||||
|
||||
public void setHeapRegionCodeRootSetsMaxSize(int heapRegionCodeRootSetsMaxSize) {
|
||||
this.heapRegionCodeRootSetsMaxSize = heapRegionCodeRootSetsMaxSize;
|
||||
}
|
||||
|
||||
public RegionsSummary getRegionCodeRootSizeAndRegions() {
|
||||
return regionCodeRootSizeAndRegions;
|
||||
}
|
||||
|
||||
public void setRegionCodeRootSizeAndRegions(RegionsSummary regionCodeRootSizeAndRegions) {
|
||||
this.regionCodeRootSizeAndRegions = regionCodeRootSizeAndRegions;
|
||||
}
|
||||
|
||||
public int getCodeRootsRepresented() {
|
||||
return codeRootsRepresented;
|
||||
}
|
||||
|
||||
public void setCodeRootsRepresented(int codeRootsRepresented) {
|
||||
this.codeRootsRepresented = codeRootsRepresented;
|
||||
}
|
||||
|
||||
public RegionsSummary getElementsByRegionCounts() {
|
||||
return elementsByRegionCounts;
|
||||
}
|
||||
|
||||
public void setElementsByRegionCounts(RegionsSummary elementsByRegionCounts) {
|
||||
this.elementsByRegionCounts = elementsByRegionCounts;
|
||||
}
|
||||
|
||||
public int getLargestAmountOfCodeRootsSize() {
|
||||
return largestAmountOfCodeRootsSize;
|
||||
}
|
||||
|
||||
public void setLargestAmountOfCodeRootsSize(int largestAmountOfCodeRootsSize) {
|
||||
this.largestAmountOfCodeRootsSize = largestAmountOfCodeRootsSize;
|
||||
}
|
||||
|
||||
public int getLargestAmountOfCodeRootsNumberOfElements() {
|
||||
return largestAmountOfCodeRootsNumberOfElements;
|
||||
}
|
||||
|
||||
public void setLargestAmountOfCodeRootsNumberOfElements(int largestAmountOfCodeRootsNumberOfElements) {
|
||||
this.largestAmountOfCodeRootsNumberOfElements = largestAmountOfCodeRootsNumberOfElements;
|
||||
}
|
||||
|
||||
/*
|
||||
Recent concurrent refinement statistics
|
||||
Processed 4907 cards
|
||||
Of 32 completed buffers:
|
||||
32 ( 93.8%) by concurrent RS threads.
|
||||
2 ( 6.2%) by mutator threads.
|
||||
Did 0 coarsenings.
|
||||
Concurrent RS threads times (s)
|
||||
0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
|
||||
Concurrent sampling threads times (s)
|
||||
0.00
|
||||
*/
|
||||
|
||||
class ConcurrentRefinementStatistics {
|
||||
private int cardsProcessed;
|
||||
private int completedBuffers;
|
||||
private int buffersCompletedByRSThreads;
|
||||
private int buffersCompletedByMutatorThreads;
|
||||
private int coarsenings;
|
||||
|
||||
ConcurrentRefinementStatistics() {
|
||||
}
|
||||
|
||||
public int getCardsProcessed() {
|
||||
return cardsProcessed;
|
||||
}
|
||||
|
||||
public void setCardsProcessed(int cardsProcessed) {
|
||||
this.cardsProcessed = cardsProcessed;
|
||||
}
|
||||
|
||||
public int getCompletedBuffers() {
|
||||
return completedBuffers;
|
||||
}
|
||||
|
||||
public void setCompletedBuffers(int completedBuffers) {
|
||||
this.completedBuffers = completedBuffers;
|
||||
}
|
||||
|
||||
public int getBuffersCompletedByRSThreads() {
|
||||
return buffersCompletedByRSThreads;
|
||||
}
|
||||
|
||||
public void setBuffersCompletedByRSThreads(int buffersCompletedByRSThreads) {
|
||||
this.buffersCompletedByRSThreads = buffersCompletedByRSThreads;
|
||||
}
|
||||
|
||||
public int getBuffersCompletedByMutatorThreads() {
|
||||
return buffersCompletedByMutatorThreads;
|
||||
}
|
||||
|
||||
public void setBuffersCompletedByMutatorThreads(int buffersCompletedByMutatorThreads) {
|
||||
this.buffersCompletedByMutatorThreads = buffersCompletedByMutatorThreads;
|
||||
}
|
||||
|
||||
public int getCoarsenings() {
|
||||
return coarsenings;
|
||||
}
|
||||
|
||||
public void setCoarsenings(int coarsenings) {
|
||||
this.coarsenings = coarsenings;
|
||||
}
|
||||
}
|
||||
|
||||
class RegionsSummary {
|
||||
|
||||
private int youngRegionsStatistics;
|
||||
private int youngRegionsCount;
|
||||
private int humonguousRegionsStatistics;
|
||||
private int humonguousRegionsCount;
|
||||
private int freeRegionsStatistics;
|
||||
private int freeRegionsCount;
|
||||
private int oldRegionsStatistics;
|
||||
private int oldRegionsCount;
|
||||
|
||||
RegionsSummary() {
|
||||
}
|
||||
|
||||
void setYoungRegionsStatistics(int value) {
|
||||
youngRegionsStatistics = value;
|
||||
}
|
||||
|
||||
void setYoungRegionsCount(int value) {
|
||||
youngRegionsCount = value;
|
||||
}
|
||||
|
||||
void setHumonguousRegionsStatistics(int value) {
|
||||
humonguousRegionsStatistics = value;
|
||||
}
|
||||
|
||||
void setHumonguousRegionsCount(int value) {
|
||||
humonguousRegionsCount = value;
|
||||
}
|
||||
|
||||
void setFreeRegionsStatistics(int value) {
|
||||
freeRegionsStatistics = value;
|
||||
}
|
||||
|
||||
void setFreeRegionsCount(int value) {
|
||||
freeRegionsCount = value;
|
||||
}
|
||||
|
||||
void setOldRegionsStatistics(int value) {
|
||||
oldRegionsStatistics = value;
|
||||
}
|
||||
|
||||
void setOldRegionsCount(int value) {
|
||||
oldRegionsCount = value;
|
||||
}
|
||||
|
||||
int getYoungRegionsStatistics() {
|
||||
return youngRegionsStatistics;
|
||||
}
|
||||
|
||||
int getYoungRegionsCount() {
|
||||
return youngRegionsCount;
|
||||
}
|
||||
|
||||
int getHumonguousRegionsStatistics() {
|
||||
return humonguousRegionsStatistics;
|
||||
}
|
||||
|
||||
int getHumonguousRegionsCount() {
|
||||
return humonguousRegionsCount;
|
||||
}
|
||||
|
||||
int getFreeRegionsStatistics() {
|
||||
return freeRegionsStatistics;
|
||||
}
|
||||
|
||||
int getFreeRegionsCount() {
|
||||
return freeRegionsCount;
|
||||
}
|
||||
|
||||
int getOldRegionsStatistics() {
|
||||
return oldRegionsStatistics;
|
||||
}
|
||||
|
||||
int getOldRegionsCount() {
|
||||
return oldRegionsCount;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.generational;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class AbortablePreClean extends CMSConcurrentEvent {
|
||||
|
||||
private final boolean abortedDueToTime;
|
||||
|
||||
public AbortablePreClean(DateTimeStamp timeStamp, double duration, double cpuTime, double wallClockTime, boolean abortDueToTime) {
|
||||
super(timeStamp, GarbageCollectionTypes.Abortable_Preclean, GCCause.UNKNOWN_GCCAUSE, duration, cpuTime, wallClockTime);
|
||||
this.abortedDueToTime = abortDueToTime;
|
||||
}
|
||||
|
||||
public boolean isAbortedDueToTime() {
|
||||
return this.abortedDueToTime;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.generational;
|
||||
|
||||
public class BinaryTreeDictionary {
|
||||
|
||||
long totalFreeSpace;
|
||||
long maxChunkSize;
|
||||
int numberOfBlocks;
|
||||
long averageBlockSize;
|
||||
int treeHeight;
|
||||
|
||||
public BinaryTreeDictionary(long totalFreeSpace, long maxChunkSize, int numberOfBlocks, long averageBlockSize, int treeHeight) {
|
||||
this.totalFreeSpace = totalFreeSpace;
|
||||
this.maxChunkSize = maxChunkSize;
|
||||
this.numberOfBlocks = numberOfBlocks;
|
||||
this.averageBlockSize = averageBlockSize;
|
||||
this.treeHeight = treeHeight;
|
||||
}
|
||||
|
||||
public long getTotalFreeSpace() {
|
||||
return totalFreeSpace;
|
||||
}
|
||||
|
||||
public long getMaxChunkSize() {
|
||||
return maxChunkSize;
|
||||
}
|
||||
|
||||
public int getNumberOfBlocks() {
|
||||
return this.numberOfBlocks;
|
||||
}
|
||||
|
||||
public long getAverageBlockSize() {
|
||||
return averageBlockSize;
|
||||
}
|
||||
|
||||
public int getTreeHeight() {
|
||||
return treeHeight;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.generational;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
abstract public class CMSConcurrentEvent extends GenerationalGCEvent implements CMSPhase {
|
||||
|
||||
double cpuTime;
|
||||
double wallClockTime;
|
||||
|
||||
protected CMSConcurrentEvent(DateTimeStamp timeStamp, GarbageCollectionTypes type, GCCause cause, double duration, double cpuTime, double wallClockTime) {
|
||||
super(timeStamp, type, cause, duration);
|
||||
this.cpuTime = cpuTime;
|
||||
this.wallClockTime = wallClockTime;
|
||||
}
|
||||
|
||||
public double getCpuTime() {
|
||||
return cpuTime;
|
||||
}
|
||||
|
||||
public double getWallClockTime() {
|
||||
return wallClockTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConcurrent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.generational;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
abstract public class CMSPauseEvent extends GenerationalGCPauseEvent implements CMSPhase {
|
||||
|
||||
public CMSPauseEvent(DateTimeStamp timeStamp, GarbageCollectionTypes gcType, GCCause cause, double duration) {
|
||||
super(timeStamp, gcType, cause, duration);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.generational;
|
||||
|
||||
public interface CMSPhase {
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.generational;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class CMSRemark extends CMSPauseEvent {
|
||||
|
||||
public CMSRemark(DateTimeStamp timeStamp, double duration) {
|
||||
this(timeStamp, GCCause.CMS_FINAL_REMARK, duration);
|
||||
}
|
||||
|
||||
public CMSRemark(DateTimeStamp timeStamp, GCCause gcCause, double duration) {
|
||||
super(timeStamp, GarbageCollectionTypes.Remark, gcCause, duration);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.generational;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class ConcurrentMark extends CMSConcurrentEvent {
|
||||
|
||||
public ConcurrentMark(DateTimeStamp timeStamp, double duration, double cpuTime, double wallClockTime) {
|
||||
super(timeStamp, GarbageCollectionTypes.ConcurrentMark, GCCause.UNKNOWN_GCCAUSE, duration, cpuTime, wallClockTime);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.generational;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class ConcurrentModeFailure extends FullGC {
|
||||
|
||||
public ConcurrentModeFailure(DateTimeStamp timeStamp, GCCause cause, double duration) {
|
||||
super(timeStamp, GarbageCollectionTypes.ConcurrentModeFailure, cause, duration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConcurrentModeFailure() {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.generational;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class ConcurrentModeInterrupted extends FullGC {
|
||||
|
||||
public ConcurrentModeInterrupted(DateTimeStamp timeStamp, GarbageCollectionTypes type, GCCause cause, double duration) {
|
||||
super(timeStamp, type, cause, duration);
|
||||
}
|
||||
|
||||
public ConcurrentModeInterrupted(DateTimeStamp timeStamp, GCCause cause, double duration) {
|
||||
this(timeStamp, GarbageCollectionTypes.ConcurrentModeInterrupted, cause, duration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConcurrentModeInterrupted() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.generational;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class ConcurrentPreClean extends CMSConcurrentEvent {
|
||||
|
||||
public ConcurrentPreClean(DateTimeStamp timeStamp, double duration, double cpuTime, double wallClockTime) {
|
||||
super(timeStamp, GarbageCollectionTypes.Concurrent_Preclean, GCCause.UNKNOWN_GCCAUSE, duration, cpuTime, wallClockTime);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.generational;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class ConcurrentReset extends CMSConcurrentEvent {
|
||||
|
||||
public ConcurrentReset(DateTimeStamp timeStamp, double duration, double cpuTime, double wallClockTime) {
|
||||
super(timeStamp, GarbageCollectionTypes.Concurrent_Reset, GCCause.UNKNOWN_GCCAUSE, duration, cpuTime, wallClockTime);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.generational;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class ConcurrentSweep extends CMSConcurrentEvent {
|
||||
|
||||
public ConcurrentSweep(DateTimeStamp timeStamp, double duration, double cpuTime, double wallClockTime) {
|
||||
super(timeStamp, GarbageCollectionTypes.Concurrent_Sweep, GCCause.UNKNOWN_GCCAUSE, duration, cpuTime, wallClockTime);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.generational;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class DefNew extends GenerationalGCPauseEvent {
|
||||
|
||||
public DefNew(DateTimeStamp timeStamp, GCCause cause, double duration) {
|
||||
super(timeStamp, GarbageCollectionTypes.DefNew, cause, duration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isYoung() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.generational;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class FullGC extends GenerationalGCPauseEvent {
|
||||
|
||||
private int dutyCycle = -1;
|
||||
|
||||
public FullGC(DateTimeStamp timeStamp, GarbageCollectionTypes type, GCCause cause, double duration) {
|
||||
super(timeStamp, type, cause, duration);
|
||||
}
|
||||
|
||||
public FullGC(DateTimeStamp timeStamp, GCCause cause, double duration) {
|
||||
super(timeStamp, GarbageCollectionTypes.FullGC, cause, duration);
|
||||
}
|
||||
|
||||
public void recordDutyCycle(int dutyCycle) {
|
||||
this.dutyCycle = dutyCycle;
|
||||
}
|
||||
|
||||
public int getDutyCycle() {
|
||||
return dutyCycle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFull() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.generational;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GCEvent;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public abstract class GenerationalGCEvent extends GCEvent {
|
||||
|
||||
protected GenerationalGCEvent(DateTimeStamp timeStamp, GarbageCollectionTypes type, GCCause cause, double duration) {
|
||||
super(timeStamp, type, cause, duration);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.generational;
|
||||
|
||||
import com.microsoft.censum.event.CPUSummary;
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.event.MemoryPoolSummary;
|
||||
import com.microsoft.censum.event.ReferenceGCSummary;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public abstract class GenerationalGCPauseEvent extends GenerationalGCEvent {
|
||||
|
||||
MemoryPoolSummary young;
|
||||
MemoryPoolSummary tenured;
|
||||
MemoryPoolSummary heap;
|
||||
MemoryPoolSummary permOrMetaspace;
|
||||
MemoryPoolSummary nonClassspace;
|
||||
MemoryPoolSummary classspace;
|
||||
ReferenceGCSummary referenceGCSummary;
|
||||
double classUnloadingProcessingTime;
|
||||
double symbolTableProcessingTime;
|
||||
double stringTableProcessingTime;
|
||||
double symbolAndStringTableProcessingTime;
|
||||
BinaryTreeDictionary binaryTreeDictionary;
|
||||
|
||||
CPUSummary cpuSummary;
|
||||
|
||||
public GenerationalGCPauseEvent(DateTimeStamp timeStamp, GarbageCollectionTypes type, GCCause cause, double duration) {
|
||||
super(timeStamp, type, cause, duration);
|
||||
}
|
||||
|
||||
public void add(MemoryPoolSummary heap) {
|
||||
this.heap = heap;
|
||||
}
|
||||
|
||||
public void add(MemoryPoolSummary young, MemoryPoolSummary heap) {
|
||||
this.add(
|
||||
young,
|
||||
heap.minus(young),
|
||||
heap);
|
||||
}
|
||||
|
||||
public void add(MemoryPoolSummary young, MemoryPoolSummary tenured, MemoryPoolSummary heap) {
|
||||
this.young = young;
|
||||
this.tenured = tenured;
|
||||
this.heap = heap;
|
||||
}
|
||||
|
||||
public void addPermOrMetaSpaceRecord(MemoryPoolSummary permOrMetaspaceRecord) {
|
||||
permOrMetaspace = permOrMetaspaceRecord;
|
||||
}
|
||||
|
||||
public void addClassspace(MemoryPoolSummary pool) {
|
||||
classspace = pool;
|
||||
}
|
||||
|
||||
public void addNonClassspace(MemoryPoolSummary pool) {
|
||||
nonClassspace = pool;
|
||||
}
|
||||
|
||||
public void add(ReferenceGCSummary referenceGCSummary) {
|
||||
this.referenceGCSummary = referenceGCSummary;
|
||||
}
|
||||
|
||||
public void add(CPUSummary summary) {
|
||||
this.cpuSummary = summary;
|
||||
}
|
||||
|
||||
public MemoryPoolSummary getYoung() {
|
||||
return this.young;
|
||||
}
|
||||
|
||||
public MemoryPoolSummary getTenured() {
|
||||
return this.tenured;
|
||||
}
|
||||
|
||||
public MemoryPoolSummary getHeap() {
|
||||
return this.heap;
|
||||
}
|
||||
|
||||
public MemoryPoolSummary getPermOrMetaspace() {
|
||||
return this.permOrMetaspace;
|
||||
}
|
||||
|
||||
public MemoryPoolSummary getNonClassspace() {
|
||||
return this.nonClassspace;
|
||||
}
|
||||
|
||||
public MemoryPoolSummary getClassspace() {
|
||||
return this.classspace;
|
||||
}
|
||||
|
||||
public ReferenceGCSummary getReferenceGCSummary() {
|
||||
return this.referenceGCSummary;
|
||||
}
|
||||
|
||||
public CPUSummary getCpuSummary() {
|
||||
return this.cpuSummary;
|
||||
}
|
||||
|
||||
public void addReferenceGCSummary(ReferenceGCSummary summary) {
|
||||
this.referenceGCSummary = summary;
|
||||
}
|
||||
|
||||
/*
|
||||
* weak, class unloading, symbol table, string table, symbol and string
|
||||
* combined as reference processing table
|
||||
*/
|
||||
public void addClassUnloadingAndStringTableProcessingDurations(double classUnloading, double symbolTable, double stringTable, double symbolAndStringTable) {
|
||||
this.classUnloadingProcessingTime = classUnloading;
|
||||
this.symbolTableProcessingTime = symbolTable;
|
||||
this.stringTableProcessingTime = stringTable;
|
||||
this.symbolAndStringTableProcessingTime = symbolAndStringTable;
|
||||
}
|
||||
|
||||
public double getClassUnloadingProcessingTime() {
|
||||
return this.classUnloadingProcessingTime;
|
||||
}
|
||||
|
||||
public double getSymbolTableProcessingTime() {
|
||||
return this.symbolTableProcessingTime;
|
||||
}
|
||||
|
||||
public double getStringTableProcessingTime() {
|
||||
return this.stringTableProcessingTime;
|
||||
}
|
||||
|
||||
public double getSymbolAndStringTableProcessingTime() {
|
||||
return this.symbolAndStringTableProcessingTime;
|
||||
}
|
||||
|
||||
public void addBinaryTreeDictionary(BinaryTreeDictionary dictionary) {
|
||||
this.binaryTreeDictionary = dictionary;
|
||||
}
|
||||
|
||||
public BinaryTreeDictionary getBinaryTreeDictionary() {
|
||||
return this.binaryTreeDictionary;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.generational;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.event.MemoryPoolSummary;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class InitialMark extends CMSPauseEvent {
|
||||
|
||||
public InitialMark(DateTimeStamp timeStamp, GCCause cause, double duration) {
|
||||
super(timeStamp, GarbageCollectionTypes.InitialMark, cause, duration);
|
||||
}
|
||||
|
||||
public InitialMark(DateTimeStamp timeStamp, double duration) {
|
||||
this(timeStamp, GCCause.UNKNOWN_GCCAUSE, duration);
|
||||
}
|
||||
|
||||
public void add(MemoryPoolSummary tenured, MemoryPoolSummary heap) {
|
||||
this.add(heap.minus(tenured), tenured, heap);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.generational;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class PSFullGC extends FullGC {
|
||||
|
||||
public PSFullGC(DateTimeStamp timeStamp, GarbageCollectionTypes type, GCCause cause, double duration) {
|
||||
super(timeStamp, type, cause, duration);
|
||||
}
|
||||
|
||||
public PSFullGC(DateTimeStamp timeStamp, GCCause cause, double duration) {
|
||||
this(timeStamp, GarbageCollectionTypes.PSFull, cause, duration);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.generational;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class PSYoungGen extends GenerationalGCPauseEvent {
|
||||
|
||||
public PSYoungGen(DateTimeStamp timeStamp, GarbageCollectionTypes type, GCCause cause, double duration) {
|
||||
super(timeStamp, type, cause, duration);
|
||||
}
|
||||
|
||||
public PSYoungGen(DateTimeStamp timeStamp, GCCause cause, double duration) {
|
||||
super(timeStamp, GarbageCollectionTypes.PSYoungGen, cause, duration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isYoung() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.generational;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.event.TLABSummary;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class ParNew extends GenerationalGCPauseEvent {
|
||||
|
||||
private TLABSummary tlabSummary = null;
|
||||
|
||||
private int dutyCycle = -1;
|
||||
|
||||
public ParNew(DateTimeStamp dateTimeStamp, GCCause gcCause, double pauseTime) {
|
||||
this(dateTimeStamp, GarbageCollectionTypes.ParNew, gcCause, pauseTime);
|
||||
}
|
||||
|
||||
public ParNew(DateTimeStamp dateTimeStamp, GarbageCollectionTypes gcCollectionType, GCCause gcCause, double pauseTime) {
|
||||
super(dateTimeStamp, gcCollectionType, gcCause, pauseTime);
|
||||
}
|
||||
|
||||
public void recordDutyCycle(int dutyCycle) {
|
||||
this.dutyCycle = dutyCycle;
|
||||
}
|
||||
|
||||
public int getDutyCycle() {
|
||||
return dutyCycle;
|
||||
}
|
||||
|
||||
public void recordTLabSummary() {
|
||||
tlabSummary = new TLABSummary();
|
||||
}
|
||||
|
||||
public TLABSummary getTlabSummary() {
|
||||
return tlabSummary;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isYoung() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.generational;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class ParNewPromotionFailed extends ParNew {
|
||||
|
||||
public ParNewPromotionFailed(DateTimeStamp dateTimeStamp, GCCause gcCause, double pauseTime) {
|
||||
super(dateTimeStamp, GarbageCollectionTypes.ParNewPromotionFailed, gcCause, pauseTime);
|
||||
}
|
||||
|
||||
public ParNewPromotionFailed(DateTimeStamp dateTimeStamp, double pauseTime) {
|
||||
this(dateTimeStamp, GCCause.PROMOTION_FAILED, pauseTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isYoung() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.generational;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class SystemGC extends FullGC {
|
||||
|
||||
public SystemGC(DateTimeStamp timeStamp, GarbageCollectionTypes type, GCCause cause, double duration) {
|
||||
super(timeStamp, type, cause, duration);
|
||||
}
|
||||
|
||||
public SystemGC(DateTimeStamp timeStamp, GCCause cause, double duration) {
|
||||
this(timeStamp, GarbageCollectionTypes.SystemGC, cause, duration);
|
||||
}
|
||||
|
||||
public SystemGC(DateTimeStamp timeStamp, double duration) {
|
||||
this(timeStamp, GarbageCollectionTypes.SystemGC, GCCause.JAVA_LANG_SYSTEM, duration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSystemGC() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.generational;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class YoungGC extends GenerationalGCPauseEvent {
|
||||
|
||||
public YoungGC(DateTimeStamp timeStamp, GarbageCollectionTypes gcType, GCCause cause, double duration) {
|
||||
super(timeStamp, gcType, cause, duration);
|
||||
}
|
||||
|
||||
public YoungGC(DateTimeStamp timeStamp, GCCause cause, double duration) {
|
||||
this(timeStamp, GarbageCollectionTypes.GC, cause, duration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isYoung() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.jvm;
|
||||
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class ApplicationConcurrentTime extends JVMEvent {
|
||||
|
||||
public ApplicationConcurrentTime(DateTimeStamp timeStamp, double duration) {
|
||||
super(timeStamp, duration);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.jvm;
|
||||
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class ApplicationRunTime extends JVMEvent {
|
||||
|
||||
public ApplicationRunTime(DateTimeStamp timeStamp, double duration) {
|
||||
super(timeStamp, duration);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.jvm;
|
||||
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class ApplicationStoppedTime extends JVMEvent {
|
||||
|
||||
private static final double NO_TTSP = -1.0d; // negative times.. don't make sense
|
||||
private boolean gcPause;
|
||||
private double timeToStopThreads;
|
||||
private VMOperations safePointReason = null;
|
||||
|
||||
public ApplicationStoppedTime(DateTimeStamp timeStamp, double duration, double timeToStopThreads, VMOperations safePointReason) {
|
||||
this(timeStamp, duration, timeToStopThreads, safePointReason.isCollection());
|
||||
this.safePointReason = safePointReason;
|
||||
}
|
||||
|
||||
public ApplicationStoppedTime(DateTimeStamp timeStamp, double duration, boolean gcPause) {
|
||||
this(timeStamp, duration, NO_TTSP, gcPause);
|
||||
}
|
||||
|
||||
public ApplicationStoppedTime(DateTimeStamp timeStamp, double duration, double timeToStopThreads, boolean gcPause) {
|
||||
super(timeStamp, duration);
|
||||
this.timeToStopThreads = timeToStopThreads;
|
||||
this.gcPause = gcPause;
|
||||
}
|
||||
|
||||
public VMOperations getSafePointReason() {
|
||||
return safePointReason;
|
||||
}
|
||||
|
||||
public double getTimeToStopThreads() {
|
||||
return this.timeToStopThreads;
|
||||
}
|
||||
|
||||
public boolean isGCPause() {
|
||||
if (safePointReason != null)
|
||||
return safePointReason.isCollection();
|
||||
return this.gcPause;
|
||||
}
|
||||
|
||||
public boolean hasTTSP() {
|
||||
return timeToStopThreads != NO_TTSP;
|
||||
}
|
||||
|
||||
public enum VMOperations {
|
||||
BulkRevokeBias(false), CGC_Operation(true), Cleanup(false),
|
||||
Deoptimize(true), EnableBiasedLocking(false), Exit(false),
|
||||
G1CollectForAllocation(true), RevokeBias(false);
|
||||
|
||||
private final boolean collection;
|
||||
|
||||
public boolean isCollection() {
|
||||
return collection;
|
||||
}
|
||||
|
||||
VMOperations(boolean collection) {
|
||||
this.collection = collection;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.jvm;
|
||||
|
||||
import com.microsoft.censum.event.MemoryPoolSummary;
|
||||
|
||||
public class ClassspaceSummary extends MemoryPoolSummary {
|
||||
|
||||
private long reserved;
|
||||
private long available;
|
||||
|
||||
public ClassspaceSummary(long before, long after, long committed, long reserved) {
|
||||
super(before, after, committed);
|
||||
this.reserved = reserved;
|
||||
}
|
||||
|
||||
public ClassspaceSummary(long before, long after, long available, long committed, long reserved) {
|
||||
super(before, after, committed);
|
||||
this.reserved = reserved;
|
||||
this.available = available;
|
||||
}
|
||||
|
||||
public long getReserved() {
|
||||
return reserved;
|
||||
}
|
||||
|
||||
public long getAvailable() {
|
||||
return available;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.jvm;
|
||||
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public abstract class JVMEvent {
|
||||
|
||||
private final DateTimeStamp timeStamp;
|
||||
private final double duration;
|
||||
|
||||
public JVMEvent(DateTimeStamp timeStamp, double duration) {
|
||||
this.timeStamp = timeStamp;
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public DateTimeStamp getDateTimeStamp() {
|
||||
return timeStamp;
|
||||
}
|
||||
|
||||
public double getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder string = new StringBuilder(getClass().getSimpleName()).append("@");
|
||||
if (timeStamp != null)
|
||||
string.append(timeStamp.toString());
|
||||
else
|
||||
string.append("unknown");
|
||||
return string.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.jvm;
|
||||
|
||||
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class JVMTermination extends JVMEvent {
|
||||
|
||||
public JVMTermination(DateTimeStamp timeStamp) {
|
||||
super(timeStamp, 0.0d);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.jvm;
|
||||
|
||||
import com.microsoft.censum.event.MemoryPoolSummary;
|
||||
|
||||
public class MetaspaceRecord extends MemoryPoolSummary {
|
||||
|
||||
public MetaspaceRecord(long before, long after, long size) {
|
||||
super(before, after, size);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.jvm;
|
||||
|
||||
import com.microsoft.censum.event.MemoryPoolSummary;
|
||||
|
||||
public class MetaspaceSummary extends MemoryPoolSummary {
|
||||
|
||||
private long reserved = -1L;
|
||||
private long available = -1L;
|
||||
|
||||
public MetaspaceSummary(long before, long after, long committed, long reserved) {
|
||||
super(before, after, committed);
|
||||
this.reserved = reserved;
|
||||
}
|
||||
|
||||
public MetaspaceSummary(long before, long after, long available, long committed, long reserved) {
|
||||
super(before, after, committed);
|
||||
this.reserved = reserved;
|
||||
this.available = available;
|
||||
}
|
||||
|
||||
public long getReserved() {
|
||||
return reserved;
|
||||
}
|
||||
|
||||
public long getAvailable() {
|
||||
return available;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.jvm;
|
||||
|
||||
import com.microsoft.censum.event.MemoryPoolSummary;
|
||||
|
||||
public class PermGenSummary extends MemoryPoolSummary {
|
||||
|
||||
public PermGenSummary(long before, long after, long size) {
|
||||
super(before, after, size);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.jvm;
|
||||
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
|
||||
public class Safepoint extends JVMEvent {
|
||||
|
||||
private String vmOperation;
|
||||
private int totalNumberOfApplicationThreads;
|
||||
private int initiallyRunning;
|
||||
private int waitingToBlock;
|
||||
|
||||
private int spinDuration;
|
||||
private int blockDuration;
|
||||
private int syncDuration;
|
||||
private int cleanupDuration;
|
||||
private int vmopDuration;
|
||||
|
||||
private int pageTrapCount;
|
||||
|
||||
public Safepoint(String vmOperationName, DateTimeStamp timeStamp, double duration) {
|
||||
super(timeStamp, duration);
|
||||
this.vmOperation = vmOperationName;
|
||||
}
|
||||
|
||||
//[threads: total initially_running wait_to_block]
|
||||
public void recordThreadCounts(int totalThreads, int initiallyRunning, int waitingToBlock) {
|
||||
this.totalNumberOfApplicationThreads = totalThreads;
|
||||
this.initiallyRunning = initiallyRunning;
|
||||
this.waitingToBlock = waitingToBlock;
|
||||
}
|
||||
|
||||
//[time: spin block sync cleanup vmop]
|
||||
public void recordDurations(int spinDuration, int blockDuration, int syncDuration, int cleanupDuration, int vmopDuration) {
|
||||
this.spinDuration = spinDuration;
|
||||
this.blockDuration = blockDuration;
|
||||
this.syncDuration = syncDuration;
|
||||
this.cleanupDuration = cleanupDuration;
|
||||
this.vmopDuration = vmopDuration;
|
||||
}
|
||||
|
||||
// page_trap_count
|
||||
public void recordPageTrapCount(int pageTrapCount) {
|
||||
this.pageTrapCount = pageTrapCount;
|
||||
}
|
||||
|
||||
public String getVmOperation() {
|
||||
return vmOperation;
|
||||
}
|
||||
|
||||
public int getTotalNumberOfApplicationThreads() {
|
||||
return totalNumberOfApplicationThreads;
|
||||
}
|
||||
|
||||
public int getInitiallyRunning() {
|
||||
return initiallyRunning;
|
||||
}
|
||||
|
||||
public int getWaitingToBlock() {
|
||||
return waitingToBlock;
|
||||
}
|
||||
|
||||
public int getSpinDuration() {
|
||||
return spinDuration;
|
||||
}
|
||||
|
||||
public int getBlockDuration() {
|
||||
return blockDuration;
|
||||
}
|
||||
|
||||
public int getSyncDuration() {
|
||||
return syncDuration;
|
||||
}
|
||||
|
||||
public int getCleanupDuration() {
|
||||
return cleanupDuration;
|
||||
}
|
||||
|
||||
public int getVmopDuration() {
|
||||
return vmopDuration;
|
||||
}
|
||||
|
||||
public int getPageTrapCount() {
|
||||
return pageTrapCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getVmOperation();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.jvm;
|
||||
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
public class SurvivorRecord extends JVMEvent {
|
||||
|
||||
private static final int THEORETICAL_MAX_TENURING_THRESHOLD = 15;
|
||||
|
||||
private final long desiredOccupancyAfterCollection;
|
||||
private int calculatedTenuringThreshold;
|
||||
private int maxTenuringThreshold;
|
||||
|
||||
// JDK bug, we have now seen a max tenuring threshold of 32, even 64
|
||||
// Fold anything older than 15 back into the 15th slot
|
||||
ArrayList<Long> bytesAtAge = null;
|
||||
|
||||
public SurvivorRecord(DateTimeStamp timeStamp, long desiredOccupancy, int calculatedTenuringThreshold, int maxTenuringThreshold) {
|
||||
super(timeStamp, 0.0d);
|
||||
this.desiredOccupancyAfterCollection = desiredOccupancy;
|
||||
setCalculatedThreshold(calculatedTenuringThreshold);
|
||||
setMaxTenuringThreshold(maxTenuringThreshold);
|
||||
}
|
||||
|
||||
private void setMaxTenuringThreshold(int maxTenuringThresholdFromLog) {
|
||||
if (maxTenuringThresholdFromLog <= THEORETICAL_MAX_TENURING_THRESHOLD) {
|
||||
this.maxTenuringThreshold = maxTenuringThresholdFromLog;
|
||||
} else {
|
||||
this.maxTenuringThreshold = THEORETICAL_MAX_TENURING_THRESHOLD;
|
||||
}
|
||||
}
|
||||
|
||||
private void setCalculatedThreshold(int calculatedTenuringThresholdFromLog) {
|
||||
if (calculatedTenuringThresholdFromLog <= THEORETICAL_MAX_TENURING_THRESHOLD) {
|
||||
this.calculatedTenuringThreshold = calculatedTenuringThresholdFromLog;
|
||||
} else {
|
||||
this.calculatedTenuringThreshold = THEORETICAL_MAX_TENURING_THRESHOLD;
|
||||
}
|
||||
}
|
||||
|
||||
public long getDesiredOccupancyAfterCollection() {
|
||||
return this.desiredOccupancyAfterCollection;
|
||||
}
|
||||
|
||||
public int getCalculatedTenuringThreshold() {
|
||||
return this.calculatedTenuringThreshold;
|
||||
}
|
||||
|
||||
public int getMaxTenuringThreshold() {
|
||||
return this.maxTenuringThreshold;
|
||||
}
|
||||
|
||||
public long getBytesAtAge(int age) {
|
||||
if (this.bytesAtAge == null) return 0L;
|
||||
return this.bytesAtAge.get(age);
|
||||
}
|
||||
|
||||
/*
|
||||
* There is a bug in the JVM that allows tenuring threshold to appear to be greater than 15.
|
||||
* Fold anything greater than 15 into 15.
|
||||
*
|
||||
*/
|
||||
public void add(int age, long bytes) {
|
||||
|
||||
if (bytesAtAge == null) {
|
||||
bytesAtAge = new ArrayList<Long>();
|
||||
bytesAtAge.add(0L); //throw away the first slow.
|
||||
}
|
||||
|
||||
if (age <= maxTenuringThreshold) {
|
||||
bytesAtAge.add(bytes);
|
||||
} else {
|
||||
bytesAtAge.set(maxTenuringThreshold, bytesAtAge.get(maxTenuringThreshold) + bytes);
|
||||
}
|
||||
}
|
||||
|
||||
public Long[] getBytesAtEachAge() {
|
||||
if (bytesAtAge == null)
|
||||
return new Long[0];
|
||||
return bytesAtAge.toArray(new Long[0]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,206 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.shenandoah;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GCEvent;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class ShenandoahCycle extends GCEvent {
|
||||
|
||||
private ERGO ergonomics;
|
||||
public ShenandoahCycle(DateTimeStamp timeStamp, GarbageCollectionTypes gcType, GCCause cause, double duration) {
|
||||
super(timeStamp, gcType, cause, duration);
|
||||
}
|
||||
|
||||
public ShenandoahCycle(DateTimeStamp timeStamp, double duration) {
|
||||
super(timeStamp, duration);
|
||||
}
|
||||
|
||||
public ShenandoahCycle(DateTimeStamp timeStamp, GCCause cause, double duration) {
|
||||
super(timeStamp, cause, duration);
|
||||
}
|
||||
|
||||
public ShenandoahCycle(DateTimeStamp timeStamp, GarbageCollectionTypes gcType, double duration) {
|
||||
super(timeStamp, gcType, duration);
|
||||
}
|
||||
|
||||
public void addErgonomics(int free, int maxFree, int humongous, double fragExternal, double fragInternal, int reserve, int maxReserve) {
|
||||
this.ergonomics = new ERGO( free, maxFree, humongous, fragExternal, fragInternal, reserve, maxReserve);
|
||||
}
|
||||
|
||||
enum Phases {
|
||||
ConcurrentReset, Pause_Initial_Mark,
|
||||
Concurrent_Marking, Concurrent_precleaning,
|
||||
Pause_Final_Mark, Concurrent_cleanup,
|
||||
Concurrent_evacuation, Pause_Init_Update_Refs,
|
||||
Concurrent_update_references, Pause_Final_Update_Refs;
|
||||
}
|
||||
|
||||
class Phase {
|
||||
|
||||
Phases phase;
|
||||
int activeWorkerThreadCount,totalWorkerThreadCount;
|
||||
|
||||
//Pacer for (Evacuation). Used CSet: 1368M, Free: 5744M, Non-Taxable: 574M, Alloc Tax Rate: 1.1x
|
||||
// duration
|
||||
|
||||
}
|
||||
|
||||
class ERGO {
|
||||
private final int free;
|
||||
private final int maxFree;
|
||||
private final int humongous;
|
||||
private final double fragExternal;
|
||||
private final double fragInternal;
|
||||
private final int reserve;
|
||||
private final int maxReserve;
|
||||
|
||||
public ERGO(int free, int maxFree, int humongous, double fragExternal, double fragInternal, int reserve, int maxReserve) {
|
||||
this.free = free;
|
||||
this.maxFree = maxFree;
|
||||
this.humongous = humongous;
|
||||
this.fragExternal = fragExternal;
|
||||
this.fragInternal = fragInternal;
|
||||
this.reserve = reserve;
|
||||
this.maxReserve = maxReserve;
|
||||
}
|
||||
|
||||
public int getFree() {
|
||||
return free;
|
||||
}
|
||||
|
||||
public int getMaxFree() {
|
||||
return maxFree;
|
||||
}
|
||||
|
||||
public int getHumongous() {
|
||||
return humongous;
|
||||
}
|
||||
|
||||
public double getFragExternal() {
|
||||
return fragExternal;
|
||||
}
|
||||
|
||||
public double getFragInternal() {
|
||||
return fragInternal;
|
||||
}
|
||||
|
||||
public int getReserve() {
|
||||
return reserve;
|
||||
}
|
||||
|
||||
public int getMaxReserve() {
|
||||
return maxReserve;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
GCCause
|
||||
"[0.876s][info][gc,ergo ] Free: 7724M, Max: 4096K regular, 7724M humongous, Frag: 0% external, 0% internal; Reserve: 412M, Max: 4096K",
|
||||
ConcurrentReset
|
||||
activeWorkerThreadCount,totalWorkerThreadCount
|
||||
Pacer for (Evacuation). Used CSet: 1368M, Free: 5744M, Non-Taxable: 574M, Alloc Tax Rate: 1.1x
|
||||
duration
|
||||
|
||||
Pause Initial Mark
|
||||
activeWorkerThreadCount,totalWorkerThreadCount
|
||||
Pacer for (Mark) Expected Live: 819M, Free: 7724M, Non-Taxable: 772M, Alloc Tax Rate: 0.4x"
|
||||
duration
|
||||
|
||||
Concurrent Marking
|
||||
activeWorkerThreadCount,totalWorkerThreadCount
|
||||
duration
|
||||
|
||||
Concurrent precleaning
|
||||
activeWorkerThreadCount,totalWorkerThreadCount
|
||||
Pacer for (Precleaning). Non-Taxable: 8192M",
|
||||
duration
|
||||
|
||||
Pause Final Mark
|
||||
activeWorkerThreadCount,totalWorkerThreadCount
|
||||
Cleaned string and symbol table, strings: 9281 processed, 0 removed, symbols: 68910 processed, 23 removed"
|
||||
Adaptive CSet Selection. Target Free: 1160M, Actual Free: 8128M, Max CSet: 341M, Min Garbage: 0B"
|
||||
Collectable Garbage: 48448K (100%), Immediate: 0B (0%), CSet: 48448K (100%)"
|
||||
Pacer for (Evacuation). Used CSet: 57344K, Free: 7716M, Non-Taxable: 771M, Alloc Tax Rate: 1.1x"
|
||||
duration
|
||||
|
||||
Concurrent cleanup
|
||||
64M->68M(8192M) 0.045ms"
|
||||
Free: 7712M, Max: 4096K regular, 7712M humongous, Frag: 0% external, 0% internal; Reserve: 411M, Max: 4096K"
|
||||
|
||||
Concurrent evacuation
|
||||
activeWorkerThreadCount,totalWorkerThreadCount
|
||||
duration
|
||||
|
||||
Pause Init Update Refs
|
||||
Pacer for (Update Refs). Used: 81920K, Free: 7712M, Non-Taxable: 771M, Alloc Tax Rate: 1.1x"
|
||||
duration
|
||||
|
||||
Concurrent update references
|
||||
activeWorkerThreadCount,totalWorkerThreadCount
|
||||
duration
|
||||
|
||||
Pause Final Update Refs
|
||||
activeWorkerThreadCount,totalWorkerThreadCount
|
||||
duration
|
||||
|
||||
Concurrent cleanup
|
||||
Concurrent cleanup 84M->28M(8192M) 0.039ms
|
||||
Free: 7752M, Max: 4096K regular, 7696M humongous, Frag: 1% external, 0% internal; Reserve: 412M, Max: 4096K",
|
||||
Metaspace: 20546K->20754K(1069056K)",
|
||||
Pacer for (Idle). Initial: 163M, Alloc Tax Rate: 1.0x"
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
"[0.876s][info][gc ] Trigger: Metadata GC Threshold",
|
||||
"[0.876s][info][gc,ergo ] Free: 7724M, Max: 4096K regular, 7724M humongous, Frag: 0% external, 0% internal; Reserve: 412M, Max: 4096K",
|
||||
"[0.876s][info][gc,start ] GC(0) Concurrent reset",
|
||||
"[0.876s][info][gc,task ] GC(0) Using 2 of 4 workers for concurrent reset",
|
||||
"[0.876s][info][gc,ergo ] GC(0) Pacer for Reset. Non-Taxable: 8192M",
|
||||
"[0.876s][info][gc ] GC(0) Concurrent reset 0.252ms",
|
||||
"[0.877s][info][gc,start ] GC(0) Pause Init Mark (process weakrefs) (unload classes)",
|
||||
"[0.877s][info][gc,task ] GC(0) Using 4 of 4 workers for init marking",
|
||||
"[0.878s][info][gc,ergo ] GC(0) Pacer for Mark. Expected Live: 819M, Free: 7724M, Non-Taxable: 772M, Alloc Tax Rate: 0.4x",
|
||||
"[0.878s][info][gc ] GC(0) Pause Init Mark (process weakrefs) (unload classes) 1.692ms",
|
||||
"[0.878s][info][gc,start ] GC(0) Concurrent marking (process weakrefs) (unload classes)",
|
||||
"[0.878s][info][gc,task ] GC(0) Using 2 of 4 workers for concurrent marking",
|
||||
"[0.883s][info][gc ] GC(0) Concurrent marking (process weakrefs) (unload classes) 4.315ms",
|
||||
"[0.883s][info][gc,start ] GC(0) Concurrent precleaning",
|
||||
"[0.883s][info][gc,task ] GC(0) Using 1 of 4 workers for concurrent preclean",
|
||||
"[0.883s][info][gc,ergo ] GC(0) Pacer for Precleaning. Non-Taxable: 8192M",
|
||||
"[0.883s][info][gc ] GC(0) Concurrent precleaning 0.232ms",
|
||||
"[0.883s][info][gc,start ] GC(0) Pause Final Mark (process weakrefs) (unload classes)",
|
||||
"[0.883s][info][gc,task ] GC(0) Using 4 of 4 workers for final marking",
|
||||
"[0.885s][info][gc,stringtable] GC(0) Cleaned string and symbol table, strings: 9281 processed, 0 removed, symbols: 68910 processed, 23 removed",
|
||||
"[0.886s][info][gc,ergo ] GC(0) Adaptive CSet Selection. Target Free: 1160M, Actual Free: 8128M, Max CSet: 341M, Min Garbage: 0B",
|
||||
"[0.886s][info][gc,ergo ] GC(0) Collectable Garbage: 48448K (100%), Immediate: 0B (0%), CSet: 48448K (100%)",
|
||||
"[0.886s][info][gc,ergo ] GC(0) Pacer for Evacuation. Used CSet: 57344K, Free: 7716M, Non-Taxable: 771M, Alloc Tax Rate: 1.1x",
|
||||
"[0.886s][info][gc ] GC(0) Pause Final Mark (process weakrefs) (unload classes) 3.175ms",
|
||||
"[0.886s][info][gc,start ] GC(0) Concurrent cleanup",
|
||||
"[0.886s][info][gc ] GC(0) Concurrent cleanup 64M->68M(8192M) 0.045ms",
|
||||
"[0.886s][info][gc,ergo ] GC(0) Free: 7712M, Max: 4096K regular, 7712M humongous, Frag: 0% external, 0% internal; Reserve: 411M, Max: 4096K",
|
||||
"[0.886s][info][gc,start ] GC(0) Concurrent evacuation",
|
||||
"[0.886s][info][gc,task ] GC(0) Using 2 of 4 workers for concurrent evacuation",
|
||||
"[0.891s][info][gc ] GC(0) Concurrent evacuation 4.539ms",
|
||||
"[0.891s][info][gc,start ] GC(0) Pause Init Update Refs",
|
||||
"[0.891s][info][gc,ergo ] GC(0) Pacer for Update Refs. Used: 81920K, Free: 7712M, Non-Taxable: 771M, Alloc Tax Rate: 1.1x",
|
||||
"[0.891s][info][gc ] GC(0) Pause Init Update Refs 0.033ms",
|
||||
"[0.891s][info][gc,start ] GC(0) Concurrent update references",
|
||||
"[0.891s][info][gc,task ] GC(0) Using 2 of 4 workers for concurrent reference update",
|
||||
"[0.895s][info][gc ] GC(0) Concurrent update references 4.072ms",
|
||||
"[0.895s][info][gc,start ] GC(0) Pause Final Update Refs",
|
||||
"[0.895s][info][gc,task ] GC(0) Using 4 of 4 workers for final reference update",
|
||||
"[0.896s][info][gc ] GC(0) Pause Final Update Refs 0.271ms",
|
||||
"[0.896s][info][gc,start ] GC(0) Concurrent cleanup",
|
||||
"[0.896s][info][gc ] GC(0) Concurrent cleanup 84M->28M(8192M) 0.039ms",
|
||||
"[0.896s][info][gc,ergo ] Free: 7752M, Max: 4096K regular, 7696M humongous, Frag: 1% external, 0% internal; Reserve: 412M, Max: 4096K",
|
||||
"[0.896s][info][gc,metaspace ] Metaspace: 20546K->20754K(1069056K)",
|
||||
"[0.896s][info][gc,ergo ] Pacer for Idle. Initial: 163M, Alloc Tax Rate: 1.0x"
|
||||
|
||||
*/
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.zgc;
|
||||
|
||||
public class OccupancySummary {
|
||||
|
||||
final private long markEnd;
|
||||
final private long reclaimStart;
|
||||
final private long reclaimEnd;
|
||||
|
||||
|
||||
public OccupancySummary(long markEnd, long reclaimStart, long reclaimEnd) {
|
||||
this.markEnd = markEnd;
|
||||
this.reclaimStart = reclaimStart;
|
||||
this.reclaimEnd = reclaimEnd;
|
||||
}
|
||||
|
||||
public long getMarkEnd() {
|
||||
return markEnd;
|
||||
}
|
||||
|
||||
public long getReclaimStart() {
|
||||
return reclaimStart;
|
||||
}
|
||||
|
||||
public long getReclaimEnd() {
|
||||
return reclaimEnd;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.zgc;
|
||||
|
||||
public class ReclaimSummary {
|
||||
|
||||
final private long reclaimStart;
|
||||
final private long reclaimEnd;
|
||||
|
||||
public ReclaimSummary(long reclaimStart, long reclaimEnd) {
|
||||
this.reclaimStart = reclaimStart;
|
||||
this.reclaimEnd = reclaimEnd;
|
||||
}
|
||||
|
||||
public long getReclaimStart() {
|
||||
return reclaimStart;
|
||||
}
|
||||
|
||||
public long getReclaimEnd() {
|
||||
return reclaimEnd;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.zgc;
|
||||
|
||||
public enum ZGCConcurrentPhases {
|
||||
|
||||
MARK("Concurrent Mark"),
|
||||
REFERENCE_PROCESSING( "Reference Processing"),
|
||||
RELOCATION_SET_SELECTION( "Relocation Set Selection"),
|
||||
RELOCATE( "Relocate");
|
||||
|
||||
private final String label;
|
||||
|
||||
ZGCConcurrentPhases(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public static ZGCConcurrentPhases fromLabel(String label) {
|
||||
for (ZGCConcurrentPhases gcType : ZGCConcurrentPhases.values()) {
|
||||
if (gcType.label.equals(label))
|
||||
return gcType;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,341 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.zgc;
|
||||
|
||||
import com.microsoft.censum.event.GCCause;
|
||||
import com.microsoft.censum.event.GCEvent;
|
||||
import com.microsoft.censum.event.GarbageCollectionTypes;
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
public class ZGCCycle extends GCEvent {
|
||||
public ZGCCycle(DateTimeStamp timeStamp, GarbageCollectionTypes gcType, GCCause cause, double duration) {
|
||||
super(timeStamp, gcType, cause, duration);
|
||||
}
|
||||
|
||||
public ZGCCycle(DateTimeStamp timeStamp, double duration) {
|
||||
super(timeStamp, duration);
|
||||
}
|
||||
|
||||
public ZGCCycle(DateTimeStamp timeStamp, GCCause cause, double duration) {
|
||||
super(timeStamp, cause, duration);
|
||||
}
|
||||
|
||||
public ZGCCycle(DateTimeStamp timeStamp, GarbageCollectionTypes gcType, double duration) {
|
||||
super(timeStamp, gcType, duration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isZGC() { return true; }
|
||||
|
||||
private DateTimeStamp pauseMarkStartTimeStamp;
|
||||
private double pauseMarkStartDuration;
|
||||
|
||||
private DateTimeStamp concurrentMarkTimeStamp;
|
||||
private double concurrentMarkDuration;
|
||||
|
||||
private DateTimeStamp pauseMarkEndTimeStamp;
|
||||
private double pauseMarkEndDuration;
|
||||
|
||||
private DateTimeStamp concurrentProcessNonStrongReferencesTimeStamp;
|
||||
private double concurrentProcessNonStrongReferencesDuration;
|
||||
|
||||
private DateTimeStamp concurrentResetRelocationSetTimeStamp;
|
||||
private double concurrentResetRelocationSetDuration;
|
||||
|
||||
private DateTimeStamp concurrentSelectRelocationSetTimeStamp;
|
||||
private double concurrentSelectRelocationSetDuration;
|
||||
|
||||
private DateTimeStamp pauseRelocateStartTimeStamp;
|
||||
private double pauseMarkRelocateDuration;
|
||||
|
||||
private DateTimeStamp concurrentRelocateTimeStamp;
|
||||
private double concurrentRelocateDuration;
|
||||
private ZGCMemoryPoolSummary metaspace;
|
||||
|
||||
private double[] load = new double[3];
|
||||
private double[] mmu = new double[6];
|
||||
|
||||
public DateTimeStamp getPauseMarkStartTimeStamp() {
|
||||
return pauseMarkStartTimeStamp;
|
||||
}
|
||||
|
||||
public double getPauseMarkStartDuration() {
|
||||
return pauseMarkStartDuration;
|
||||
}
|
||||
|
||||
public void setPauseMarkStart(DateTimeStamp pauseMarkStartTimeStamp, double duration) {
|
||||
this.pauseMarkStartTimeStamp = pauseMarkStartTimeStamp;
|
||||
this.pauseMarkStartDuration = duration;
|
||||
}
|
||||
|
||||
public DateTimeStamp getConcurrentMarkTimeStamp() {
|
||||
return concurrentMarkTimeStamp;
|
||||
}
|
||||
|
||||
public double getConcurrentMarkDuration() {
|
||||
return concurrentMarkDuration;
|
||||
}
|
||||
|
||||
public void setConcurrentMark(DateTimeStamp concurrentMarkTimeStamp, double duration) {
|
||||
this.concurrentMarkTimeStamp = concurrentMarkTimeStamp;
|
||||
this.concurrentMarkDuration = duration;
|
||||
}
|
||||
|
||||
public DateTimeStamp getPauseMarkEndTimeStamp() {
|
||||
return pauseMarkEndTimeStamp;
|
||||
}
|
||||
|
||||
public double getPauseMarkEndDuration() {
|
||||
return pauseMarkEndDuration;
|
||||
}
|
||||
|
||||
public void setPauseMarkEnd(DateTimeStamp pauseMarkEndTimeStamp, double duration) {
|
||||
this.pauseMarkEndTimeStamp = pauseMarkEndTimeStamp;
|
||||
this.pauseMarkEndDuration = duration;
|
||||
}
|
||||
|
||||
public DateTimeStamp getConcurrentProcessNonStrongReferencesTimeStamp() {
|
||||
return concurrentProcessNonStrongReferencesTimeStamp;
|
||||
}
|
||||
|
||||
public double getConcurrentProcessNonStrongReferencesDuration() {
|
||||
return concurrentProcessNonStrongReferencesDuration;
|
||||
}
|
||||
|
||||
public void setConcurrentProcessNonStrongReferences(DateTimeStamp concurrentProcessNonStrongReferencesTimeStamp, double duration) {
|
||||
this.concurrentProcessNonStrongReferencesTimeStamp = concurrentProcessNonStrongReferencesTimeStamp;
|
||||
this.concurrentProcessNonStrongReferencesDuration = duration;
|
||||
}
|
||||
|
||||
public DateTimeStamp getConcurrentResetRelocationSetTimeStamp() {
|
||||
return concurrentResetRelocationSetTimeStamp;
|
||||
}
|
||||
|
||||
public double getConcurrentResetRelocationSetDuration() {
|
||||
return concurrentResetRelocationSetDuration;
|
||||
}
|
||||
|
||||
public void setConcurrentResetRelocationSet(DateTimeStamp concurrentResetRelocationSetTimeStamp, double duration) {
|
||||
this.concurrentResetRelocationSetTimeStamp = concurrentResetRelocationSetTimeStamp;
|
||||
this.concurrentResetRelocationSetDuration = duration;
|
||||
}
|
||||
|
||||
public DateTimeStamp getConcurrentSelectRelocationSetTimeStamp() {
|
||||
return concurrentSelectRelocationSetTimeStamp;
|
||||
}
|
||||
|
||||
public double getConcurrentSelectRelocationSetDuration() {
|
||||
return concurrentSelectRelocationSetDuration;
|
||||
}
|
||||
|
||||
public void setConcurrentSelectRelocationSet(DateTimeStamp concurrentSelectRelocationSetTimeStamp, double duration) {
|
||||
this.concurrentSelectRelocationSetTimeStamp = concurrentSelectRelocationSetTimeStamp;
|
||||
this.concurrentSelectRelocationSetDuration = duration;
|
||||
}
|
||||
|
||||
public DateTimeStamp getPauseRelocateStartTimeStamp() {
|
||||
return pauseRelocateStartTimeStamp;
|
||||
}
|
||||
|
||||
public double getPauseRelocateStartDuration() {
|
||||
return pauseMarkRelocateDuration;
|
||||
}
|
||||
|
||||
public void setPauseRelocateStart(DateTimeStamp pauseRelocateStartTimeStamp, double duration) {
|
||||
this.pauseRelocateStartTimeStamp = pauseRelocateStartTimeStamp;
|
||||
this.pauseMarkRelocateDuration = duration;
|
||||
}
|
||||
|
||||
public DateTimeStamp getConcurrentRelocateTimeStamp() {
|
||||
return concurrentRelocateTimeStamp;
|
||||
}
|
||||
|
||||
public double getConcurrentRelocateDuration() {
|
||||
return concurrentRelocateDuration;
|
||||
}
|
||||
|
||||
public void setConcurrentRelocate(DateTimeStamp concurrentRelocateTimeStamp, double duration) {
|
||||
this.concurrentRelocateTimeStamp = concurrentRelocateTimeStamp;
|
||||
this.concurrentRelocateDuration = duration;
|
||||
}
|
||||
|
||||
//Memory
|
||||
private ZGCMemoryPoolSummary markStart;
|
||||
private ZGCMemoryPoolSummary markEnd;
|
||||
private ZGCMemoryPoolSummary relocateStart;
|
||||
private ZGCMemoryPoolSummary relocateEnd;
|
||||
private OccupancySummary live;
|
||||
private OccupancySummary allocated;
|
||||
private OccupancySummary garbage;
|
||||
private ReclaimSummary reclaimed;
|
||||
private ReclaimSummary memorySummary;
|
||||
|
||||
public void setMarkStart(ZGCMemoryPoolSummary summary) {
|
||||
this.markStart = summary;
|
||||
}
|
||||
|
||||
public void setMarkEnd(ZGCMemoryPoolSummary summary) {
|
||||
this.markEnd = summary;
|
||||
}
|
||||
|
||||
public void setRelocateStart(ZGCMemoryPoolSummary summary) {
|
||||
this.relocateStart = summary;
|
||||
}
|
||||
|
||||
public void setRelocateEnd(ZGCMemoryPoolSummary summary) {
|
||||
this.relocateEnd = summary;
|
||||
}
|
||||
|
||||
public void setLive(OccupancySummary summary) {
|
||||
this.live = summary;
|
||||
}
|
||||
|
||||
public void setAllocated(OccupancySummary summary) {
|
||||
this.allocated = summary;
|
||||
}
|
||||
|
||||
public void setGarbage(OccupancySummary summary) {
|
||||
this.garbage = summary;
|
||||
}
|
||||
|
||||
public void setReclaimed(ReclaimSummary summary) {
|
||||
this.reclaimed = summary;
|
||||
}
|
||||
|
||||
public void setMemorySummary(ReclaimSummary summary) {
|
||||
this.memorySummary = summary;
|
||||
}
|
||||
|
||||
public ZGCMemoryPoolSummary getMarkStart() {
|
||||
return markStart;
|
||||
}
|
||||
|
||||
public ZGCMemoryPoolSummary getMarkEnd() {
|
||||
return markEnd;
|
||||
}
|
||||
|
||||
public ZGCMemoryPoolSummary getRelocateStart() {
|
||||
return relocateStart;
|
||||
}
|
||||
|
||||
public ZGCMemoryPoolSummary getRelocateEnd() {
|
||||
return relocateEnd;
|
||||
}
|
||||
|
||||
public OccupancySummary getLive() {
|
||||
return live;
|
||||
}
|
||||
|
||||
public OccupancySummary getAllocated() {
|
||||
return allocated;
|
||||
}
|
||||
|
||||
public OccupancySummary getGarbage() {
|
||||
return garbage;
|
||||
}
|
||||
|
||||
public ReclaimSummary getReclaimed() {
|
||||
return reclaimed;
|
||||
}
|
||||
|
||||
public ReclaimSummary getMemorySummary() {
|
||||
return memorySummary;
|
||||
}
|
||||
|
||||
public void setLoadAverages(double[] load) {
|
||||
this.load = load;
|
||||
}
|
||||
public double getLoadAverageAt(int time) {
|
||||
switch (time) {
|
||||
case 1:
|
||||
return load[0];
|
||||
case 5:
|
||||
return load[1];
|
||||
case 15:
|
||||
return load[2];
|
||||
default:
|
||||
return 0.0d;
|
||||
}
|
||||
}
|
||||
|
||||
public void setMMU(double[] mmu) {
|
||||
this.mmu = mmu;
|
||||
}
|
||||
|
||||
public double getMMU(int percentage) {
|
||||
switch (percentage) {
|
||||
case 2:
|
||||
return mmu[0];
|
||||
case 5:
|
||||
return mmu[1];
|
||||
case 10:
|
||||
return mmu[2];
|
||||
case 20:
|
||||
return mmu[3];
|
||||
case 50:
|
||||
return mmu[4];
|
||||
case 100:
|
||||
return mmu[5];
|
||||
default:
|
||||
return 0.0d;
|
||||
}
|
||||
}
|
||||
|
||||
public void setMetaspace(ZGCMemoryPoolSummary summary) {
|
||||
this.metaspace = summary;
|
||||
}
|
||||
public ZGCMemoryPoolSummary getMetaspace() {
|
||||
return metaspace;
|
||||
}
|
||||
}
|
||||
|
||||
// Concurrent Mark duration
|
||||
// Pause mark end duration
|
||||
// Concurrent reference processing duration
|
||||
// Concurrent reset relocation set duration
|
||||
// Concurrent select relocation set duration
|
||||
// Pause relocate start
|
||||
// Load
|
||||
// MMU
|
||||
// Concurrent relocate
|
||||
// Relocation volume
|
||||
// NMethods, registered, unregistered
|
||||
// Metaspace used, capacity committed, reserved
|
||||
// Soft, weak, final, phantom.. encountered, discovered, enqueued
|
||||
// Memory stats
|
||||
|
||||
/*
|
||||
"[3.558s][info ][gc,start ] GC(3) Garbage Collection (Warmup)",
|
||||
"[3.559s][info ][gc,phases ] GC(3) Pause Mark Start 0.460ms",
|
||||
"[3.573s][info ][gc,phases ] GC(3) Concurrent Mark 14.621ms",
|
||||
"[3.574s][info ][gc,phases ] GC(3) Pause Mark End 0.830ms",
|
||||
"[3.578s][info ][gc,phases ] GC(3) Concurrent Process Non-Strong References 3.654ms",
|
||||
"[3.578s][info ][gc,phases ] GC(3) Concurrent Reset Relocation Set 0.194ms",
|
||||
"[3.582s][info ][gc,phases ] GC(3) Concurrent Select Relocation Set 3.193ms",
|
||||
"[3.583s][info ][gc,phases ] GC(3) Pause Relocate Start 0.794ms",
|
||||
"[3.596s][info ][gc,phases ] GC(3) Concurrent Relocate 12.962ms",
|
||||
"[3.596s][info ][gc,load ] GC(3) Load: 4.28/3.95/3.22",
|
||||
"[3.596s][info ][gc,mmu ] GC(3) MMU: 2ms/32.7%, 5ms/60.8%, 10ms/80.4%, 20ms/85.4%, 50ms/90.8%, 100ms/95.4%",
|
||||
"[3.596s][info ][gc,marking ] GC(3) Mark: 1 stripe(s), 2 proactive flush(es), 1 terminate flush(es), 1 completion(s), 0 continuation(s)",
|
||||
"[3.596s][info ][gc,reloc ] GC(3) Relocation: Successful, 6M relocated",
|
||||
"[3.596s][info ][gc,nmethod ] GC(3) NMethods: 1163 registered, 0 unregistered",
|
||||
"[3.596s][info ][gc,metaspace ] GC(3) Metaspace: 14M used, 15M capacity, 15M committed, 16M reserved",
|
||||
"[3.596s][info ][gc,ref ] GC(3) Soft: 391 encountered, 0 discovered, 0 enqueued",
|
||||
"[3.596s][info ][gc,ref ] GC(3) Weak: 587 encountered, 466 discovered, 0 enqueued",
|
||||
"[3.596s][info ][gc,ref ] GC(3) Final: 799 encountered, 0 discovered, 0 enqueued",
|
||||
"[3.596s][info ][gc,ref ] GC(3) Phantom: 33 encountered, 1 discovered, 0 enqueued",
|
||||
"[3.596s][info ][gc,heap ] GC(3) Min Capacity: 8M(0%)",
|
||||
"[3.596s][info ][gc,heap ] GC(3) Max Capacity: 4096M(100%)",
|
||||
"[3.596s][info ][gc,heap ] GC(3) Soft Max Capacity: 4096M(100%)",
|
||||
"[3.596s][info ][gc,heap ] GC(3) Mark Start Mark End Relocate Start Relocate End High Low",
|
||||
"[3.596s][info ][gc,heap ] GC(3) Capacity: 936M (23%) 1074M (26%) 1074M (26%) 1074M (26%) 1074M (26%) 936M (23%)",
|
||||
"[3.596s][info ][gc,heap ] GC(3) Reserve: 42M (1%) 42M (1%) 42M (1%) 42M (1%) 42M (1%) 42M (1%)",
|
||||
"[3.596s][info ][gc,heap ] GC(3) Free: 3160M (77%) 3084M (75%) 3852M (94%) 3868M (94%) 3930M (96%) 3022M (74%)",
|
||||
"[3.596s][info ][gc,heap ] GC(3) Used: 894M (22%) 970M (24%) 202M (5%) 186M (5%) 1032M (25%) 124M (3%)",
|
||||
"[3.596s][info ][gc,heap ] GC(3) Live: - 8M (0%) 8M (0%) 8M (0%) - -",
|
||||
"[3.596s][info ][gc,heap ] GC(3) Allocated: - 172M (4%) 172M (4%) 376M (9%) - -",
|
||||
"[3.596s][info ][gc,heap ] GC(3) Garbage: - 885M (22%) 117M (3%) 5M (0%) - -",
|
||||
"[3.596s][info ][gc,heap ] GC(3) Reclaimed: - - 768M (19%) 880M (21%) - -",
|
||||
"[3.596s][info ][gc ] GC(3) Garbage Collection (Warmup) 894M(22%)->186M(5%)"
|
||||
|
||||
*/
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.zgc;
|
||||
|
||||
public class ZGCMemoryPoolSummary {
|
||||
|
||||
// these are effectively final but David likes to see an explicit final. In Java 14 this could be a Record.
|
||||
final private long capacity;
|
||||
final private long reserved;
|
||||
final private long free;
|
||||
final private long used;
|
||||
|
||||
public ZGCMemoryPoolSummary(long capacity, long reserved, long free, long used) {
|
||||
this.capacity = capacity;
|
||||
this.reserved = reserved;
|
||||
this.free = free;
|
||||
this.used = used;
|
||||
}
|
||||
|
||||
public long getCapacity() {
|
||||
return this.capacity;
|
||||
}
|
||||
|
||||
public long getReserved() {
|
||||
return this.reserved;
|
||||
}
|
||||
|
||||
public long getFree() {
|
||||
return this.free;
|
||||
}
|
||||
|
||||
public long getUsed() {
|
||||
return this.used;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.event.zgc;
|
||||
|
||||
public enum ZGCPauseTypes {
|
||||
|
||||
MARK_START("Mark Start"),
|
||||
MARK_END( "Mark End"),
|
||||
RELOCATE_START( "Relocate Start");
|
||||
|
||||
private final String label;
|
||||
|
||||
ZGCPauseTypes(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public static ZGCPauseTypes fromLabel(String label) {
|
||||
for (ZGCPauseTypes gcType : ZGCPauseTypes.values()) {
|
||||
if (gcType.label.equals(label))
|
||||
return gcType;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public interface DataSource<T> {
|
||||
|
||||
Stream<T> stream() throws IOException;
|
||||
|
||||
T endOfData();
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.io;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public abstract class FileDataSource<T> implements DataSource<T> {
|
||||
|
||||
protected final Path path;
|
||||
protected final FileDataSourceMetaData metaData;
|
||||
|
||||
protected FileDataSource(Path path) {
|
||||
this.path = path;
|
||||
this.metaData = new FileDataSourceMetaData(path);
|
||||
}
|
||||
|
||||
public Path getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public FileDataSourceMetaData getMetaData() {
|
||||
return metaData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return path.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.io;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
public class FileDataSourceMetaData {
|
||||
|
||||
private final static Logger LOG = Logger.getLogger(FileDataSourceMetaData.class.getName());
|
||||
|
||||
private static final int GZIP_MAGIC1 = 0x1F;
|
||||
private static final int GZIP_MAGIC2 = 0x8b;
|
||||
|
||||
private static final int ZIP_MAGIC1 = 0x50;
|
||||
private static final int ZIP_MAGIC2 = 0x4b;
|
||||
|
||||
private boolean zip = false;
|
||||
private boolean gzip = false;
|
||||
private int numberOfFiles = -1;
|
||||
|
||||
private final ArrayList<Path> logFiles = new ArrayList<>();
|
||||
private final Path path;
|
||||
|
||||
public FileDataSourceMetaData(Path path) {
|
||||
this.path = path;
|
||||
magic(path);
|
||||
}
|
||||
|
||||
private boolean magic(Path path, int field1, int field2) {
|
||||
try (FileInputStream magicByteReader = new FileInputStream(path.toFile())) {
|
||||
int magicByte1 = magicByteReader.read();
|
||||
int magicByte2 = magicByteReader.read();
|
||||
return magicByte1 == field1 && magicByte2 == field2;
|
||||
} catch (IOException ioe) {
|
||||
LOG.warning(ioe.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void magic(Path path) {
|
||||
|
||||
try {
|
||||
if (Files.isDirectory(path)) {
|
||||
Files.list(path).forEach(child -> logFiles.add(child));
|
||||
this.numberOfFiles = logFiles.size();
|
||||
} else if (Files.isRegularFile(path)) {
|
||||
if (magic(path, ZIP_MAGIC1, ZIP_MAGIC2)) {
|
||||
this.zip = true;
|
||||
this.numberOfFiles = countNumberOfEntries();
|
||||
} else if (magic(path, GZIP_MAGIC1, GZIP_MAGIC2)) {
|
||||
this.gzip = true;
|
||||
this.numberOfFiles = 1; //todo, is this a tar entry???
|
||||
} else {
|
||||
this.numberOfFiles = 1;
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
LOG.warning(ioe.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private int countNumberOfEntries() {
|
||||
long count = -1;
|
||||
try {
|
||||
count = new ZipFile(path.toFile()).stream().filter(zipEntry -> !zipEntry.isDirectory()).count();
|
||||
} catch (IOException ioe) {
|
||||
LOG.warning(ioe.getMessage());
|
||||
}
|
||||
return (int) count;
|
||||
}
|
||||
|
||||
|
||||
public int getNumberOfFiles() {
|
||||
return this.numberOfFiles;
|
||||
}
|
||||
|
||||
public boolean isZip() {
|
||||
return this.zip;
|
||||
}
|
||||
|
||||
public boolean isGZip() {
|
||||
return this.gzip;
|
||||
}
|
||||
|
||||
public boolean isFile() {
|
||||
return !(isGZip() || isZip() || isDirectory());
|
||||
}
|
||||
|
||||
public boolean isDirectory() {
|
||||
return path.toFile().isDirectory();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package com.microsoft.censum.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
||||
public abstract class GCLogFile extends FileDataSource<String> {
|
||||
|
||||
public static final String END_OF_DATA_SENTINAL = "END_OF_DATA_SENTINAL";
|
||||
|
||||
private final boolean unifiedFormat;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param path The path to the GCLogFile or, in the case of rotating log files, the parent directory.
|
||||
* @param unifiedFormat Whether the log file is in unified (JEP 158) format
|
||||
*/
|
||||
protected GCLogFile(Path path, boolean unifiedFormat) {
|
||||
super(path);
|
||||
this.unifiedFormat = unifiedFormat;
|
||||
}
|
||||
|
||||
public boolean isUnifiedFormat() { return unifiedFormat; }
|
||||
|
||||
@Override
|
||||
public String endOfData() {
|
||||
return END_OF_DATA_SENTINAL;
|
||||
}
|
||||
|
||||
// match a line starting with a unified logging decorator,
|
||||
// e.g., [0.011s][info ][gc ] Using G1
|
||||
// But have to watch out for things like [ParNew...
|
||||
private static final Pattern LINE_STARTS_WITH_DECORATOR = Pattern.compile("^\\[\\d.+?\\]");
|
||||
private static final int SHOULD_HAVE_SEEN_A_UNIFIED_DECORATOR_BY_THIS_LINE_IN_THE_LOG = 25;
|
||||
|
||||
/* package */ static boolean isUnifiedLogging(Stream<String> stream) throws IOException {
|
||||
return firstNLines(stream, SHOULD_HAVE_SEEN_A_UNIFIED_DECORATOR_BY_THIS_LINE_IN_THE_LOG)
|
||||
.map(LINE_STARTS_WITH_DECORATOR::matcher)
|
||||
.anyMatch(Matcher::find);
|
||||
}
|
||||
|
||||
private static Stream<String> firstNLines(Stream<String> stream, int limit) {
|
||||
return stream.
|
||||
filter(Objects::nonNull).
|
||||
map(String::trim).
|
||||
filter(s -> s.length() > 0).
|
||||
limit(limit);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,261 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.io;
|
||||
|
||||
import com.microsoft.censum.time.DateTimeStamp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class GarbageCollectionLogFileSegment {
|
||||
|
||||
private static final String ROTATING_LOG_SUFFIX = ".*\\.(\\d+)(\\.current)?$";
|
||||
private static final Pattern ROTATING_LOG_PATTERN = Pattern.compile(ROTATING_LOG_SUFFIX);
|
||||
|
||||
// Generic tokens
|
||||
private static final String DECIMAL_POINT = "(?:\\.|,)";
|
||||
private static final String INTEGER = "\\d+";
|
||||
private static final String DATE = "\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}[\\+|\\-]\\d{4}";
|
||||
private static final String TIME = INTEGER + DECIMAL_POINT + "\\d{3}";
|
||||
|
||||
// Pre-unified tokens
|
||||
private static final String TIMESTAMP = "(" + TIME + "): ";
|
||||
private static final String DATE_STAMP = "(" + DATE + "): ";
|
||||
private static final String DATE_TIMESTAMP = "^(?:" + DATE_STAMP + ")?" + TIMESTAMP;
|
||||
|
||||
// 2017-09-07T09:00:12.795+0200: 0.716:
|
||||
private static final Pattern PREUNIFIED_DATE_TIMESTAMP = Pattern.compile(DATE_TIMESTAMP);
|
||||
|
||||
// Unified Tokens
|
||||
private static final String DATE_TAG = "\\[" + DATE + "\\]";
|
||||
private static final String UPTIME_TAG = "\\[" + TIME + "s\\]";
|
||||
|
||||
// JEP 158 has ISO-8601 time and uptime in seconds and milliseconds as the first two decorators.
|
||||
private static final Pattern UNIFIED_DATE_TIMESTAMP= Pattern.compile("^(" + DATE_TAG + ")?(" + UPTIME_TAG + ")?");
|
||||
|
||||
private final Path path;
|
||||
private final int segmentIndex;
|
||||
private final boolean current;
|
||||
private DateTimeStamp endTime = null;
|
||||
private DateTimeStamp startTime = null;
|
||||
|
||||
public GarbageCollectionLogFileSegment(Path path) {
|
||||
this.path = path;
|
||||
|
||||
final String filename = path.getFileName().toString();
|
||||
Matcher matcher = ROTATING_LOG_PATTERN.matcher(filename);
|
||||
if (matcher.matches()) {
|
||||
segmentIndex = Integer.parseInt(matcher.group(1));
|
||||
current = ".current".equals(matcher.group(2));
|
||||
} else {
|
||||
// unified log with no number is the current file
|
||||
segmentIndex = Integer.MAX_VALUE;
|
||||
current = true;
|
||||
}
|
||||
}
|
||||
|
||||
public Path getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public int getSegmentIndex() {
|
||||
return segmentIndex;
|
||||
}
|
||||
|
||||
public Stream<String> stream() {
|
||||
try {
|
||||
return Files.lines(path);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isCurrent() {
|
||||
return current;
|
||||
}
|
||||
|
||||
public DateTimeStamp ageOfJVMAtLogStart() throws IOException {
|
||||
if (startTime == null)
|
||||
startTime = scanForTimeOfLogStart(path);
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public DateTimeStamp ageOfJVMAtLogEnd() throws IOException {
|
||||
if (endTime == null)
|
||||
endTime = scanForTimeOfLogEnd(path);
|
||||
return endTime;
|
||||
}
|
||||
|
||||
// Define the maximum time (in milliseconds) between two rotating logs for them to be considered contiguous.
|
||||
private static long MAX_INTERSITCE = Long.getLong("max-rotating-log-interstice", 30 * 1000);
|
||||
|
||||
// does this log begin after otherSegment ends
|
||||
// log roll over has no JVM age.. can we estimate this...
|
||||
public boolean isContiguousWith(GarbageCollectionLogFileSegment otherSegment) {
|
||||
// Compare by calendar date, if possible.
|
||||
double delta = rolloverDelta(this, otherSegment);
|
||||
if (Double.isNaN(delta)) {
|
||||
return false;
|
||||
}
|
||||
long intersticialDelta = (long)(delta * 1000d);
|
||||
return (0 <= intersticialDelta) && (intersticialDelta < MAX_INTERSITCE);
|
||||
}
|
||||
|
||||
// calculate the delta between the start of newSegment and the end of oldSegment.
|
||||
static double rolloverDelta(GarbageCollectionLogFileSegment newSegment, GarbageCollectionLogFileSegment oldSegment) {
|
||||
DateTimeStamp startAge = null;
|
||||
DateTimeStamp endAge = null;
|
||||
try {
|
||||
startAge = newSegment.ageOfJVMAtLogStart();
|
||||
endAge = oldSegment.ageOfJVMAtLogEnd();
|
||||
} catch (IOException e) {
|
||||
// TODO: no access to logger here...
|
||||
return Double.NaN;
|
||||
}
|
||||
|
||||
if (startAge == null || endAge == null) {
|
||||
return Double.NaN;
|
||||
}
|
||||
|
||||
// Compare by calendar date, not uptime, if possible.
|
||||
final double startTime;
|
||||
final double endTime;
|
||||
if (startAge.hasDateStamp() && endAge.hasDateStamp()) {
|
||||
ZonedDateTime startDate = startAge.getDateTime();
|
||||
startTime = (double)startDate.toEpochSecond() + (double)startDate.getNano() / 1_000_000_000d;
|
||||
|
||||
ZonedDateTime endDate = endAge.getDateTime();
|
||||
endTime = (double)endDate.toEpochSecond() + (double)endDate.getNano() / 1_000_000_000d;
|
||||
|
||||
} else {
|
||||
startTime = startAge.getTimeStamp();
|
||||
endTime = endAge.getTimeStamp();
|
||||
}
|
||||
return startTime - endTime;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return path.toFile().toString();
|
||||
}
|
||||
|
||||
private static Matcher matcher(String line) {
|
||||
if (line.startsWith("[")) {
|
||||
return UNIFIED_DATE_TIMESTAMP.matcher(line);
|
||||
} else {
|
||||
return PREUNIFIED_DATE_TIMESTAMP.matcher(line);
|
||||
}
|
||||
}
|
||||
|
||||
private static DateTimeStamp calculateDateTimeStamp(Matcher matcher) {
|
||||
if (matcher.pattern() == UNIFIED_DATE_TIMESTAMP) {
|
||||
return calclateUnifiedDateTimeStamp(matcher);
|
||||
} else {
|
||||
return calculatePreUnifiedDateTimeStamp(matcher);
|
||||
}
|
||||
}
|
||||
|
||||
// [2020-04-30T12:01:11.231-0400][2020-04-30T16:01:11.231+0000][0.009s][1588262471231ms][9ms][270937237146899ns][93577ns]
|
||||
private static DateTimeStamp calclateUnifiedDateTimeStamp(Matcher matcher) {
|
||||
String t = matcher.group(1);
|
||||
String time = t != null ? t.substring(1, t.length()-1) : null;
|
||||
String u = matcher.group(2);
|
||||
double uptime = u != null ? parseDouble(u.substring(1, u.length()-2)) : -1.0d;
|
||||
return new DateTimeStamp(time, uptime);
|
||||
}
|
||||
|
||||
// 2017-09-07T09:00:12.795+0200: 0.716
|
||||
// group(1) = 2017-09-07T09:00:12.795+0200, group(2) = 0, group(3) = 716
|
||||
private static DateTimeStamp calculatePreUnifiedDateTimeStamp(Matcher matcher) {
|
||||
String dateStamp = matcher.group(1);
|
||||
double timeStamp = matcher.group(2) != null ? parseDouble(matcher.group(2)) : -1.0d;
|
||||
return new DateTimeStamp(dateStamp, timeStamp);
|
||||
}
|
||||
|
||||
private static double parseDouble(String string) {
|
||||
if (string == null) return Double.NaN;
|
||||
return Double.parseDouble(string.replace(',','.'));
|
||||
}
|
||||
|
||||
private static DateTimeStamp scanForTimeOfLogStart(Path path) throws IOException {
|
||||
return Files.lines(path)
|
||||
.map(GarbageCollectionLogFileSegment::matcher)
|
||||
.filter(Matcher::find)
|
||||
.findFirst()
|
||||
.map(GarbageCollectionLogFileSegment::calculateDateTimeStamp)
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
private static DateTimeStamp scanForTimeOfLogEnd(Path path) throws IOException {
|
||||
return tail(path,100).stream()
|
||||
.map(GarbageCollectionLogFileSegment::matcher)
|
||||
.filter(Matcher::find)
|
||||
.map(GarbageCollectionLogFileSegment::calculateDateTimeStamp)
|
||||
.max(Comparator.comparing(dateTimeStamp -> dateTimeStamp != null ? dateTimeStamp.getTimeStamp() : 0))
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* todo: implementation may be a bit ugly...
|
||||
* https://codereview.stackexchange.com/questions/79039/get-the-tail-of-a-file-the-last-10-lines
|
||||
* Tail is not a class, it's a method so the solution in stackoverflow isn't correct but the core
|
||||
* could be used here as it's cleaner
|
||||
*
|
||||
* @param numberOfLines
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
private static ArrayList<String> tail(Path path, int numberOfLines) throws IOException {
|
||||
|
||||
char LF = '\n';
|
||||
char CR = '\r';
|
||||
boolean foundEOL = false;
|
||||
char eol = 0;
|
||||
RandomAccessFile randomAccessFile = new RandomAccessFile(path.toFile(), "r");
|
||||
long currentPosition = randomAccessFile.length() - 1;
|
||||
int linesFound = 0;
|
||||
|
||||
while (currentPosition > 0 && !foundEOL) {
|
||||
randomAccessFile.seek(currentPosition);
|
||||
char character = (char) randomAccessFile.readByte();
|
||||
if (character == LF) {
|
||||
eol = LF;
|
||||
randomAccessFile.seek(currentPosition - 1);
|
||||
character = (char) randomAccessFile.readByte();
|
||||
if (character == CR)
|
||||
eol = CR;
|
||||
foundEOL = true;
|
||||
} else if (character == CR && !foundEOL) {
|
||||
eol = CR;
|
||||
foundEOL = true;
|
||||
} else
|
||||
currentPosition--;
|
||||
}
|
||||
|
||||
currentPosition = randomAccessFile.length() - 1;
|
||||
|
||||
while (currentPosition > 0 && linesFound < numberOfLines) {
|
||||
randomAccessFile.seek(--currentPosition);
|
||||
char character = (char) randomAccessFile.readByte();
|
||||
if (eol == character)
|
||||
linesFound++;
|
||||
}
|
||||
|
||||
ArrayList<String> lines = new ArrayList<>();
|
||||
if (linesFound > 0) {
|
||||
String line;
|
||||
while ((line = randomAccessFile.readLine()) != null) {
|
||||
lines.add(line);
|
||||
}
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,266 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
package com.microsoft.censum.io;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.SequenceInputStream;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Vector;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
public class RotatingGCLogFile extends GCLogFile {
|
||||
|
||||
private final static Logger LOGGER = Logger.getLogger(RotatingGCLogFile.class.getName());
|
||||
|
||||
private static boolean isUnifiedLogging(Path path) {
|
||||
try {
|
||||
final FileDataSourceMetaData metadata = new FileDataSourceMetaData(path);
|
||||
|
||||
final List<GarbageCollectionLogFileSegment> segments;
|
||||
if (metadata.isZip() || metadata.isGZip()) {
|
||||
//TODO: add code to ensure correct order to stream files in zip and gzip files
|
||||
segments = Collections.EMPTY_LIST;
|
||||
} else {
|
||||
segments = findGCLogSegments(path);
|
||||
}
|
||||
return isUnifiedLogging(path, segments);
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.WARNING, "cannot determine whether " + path + " is a unified log format");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isUnifiedLogging(Path path, List<GarbageCollectionLogFileSegment> segments) {
|
||||
// TODO: if isUnifiedLogging is false, assert that the file is pre-unified.
|
||||
// if file is neither unified nor pre-unified, then we're dealing with
|
||||
// something we can't handle.
|
||||
return segments.stream()
|
||||
.map(GarbageCollectionLogFileSegment::stream)
|
||||
.anyMatch(s -> {
|
||||
try {
|
||||
return GCLogFile.isUnifiedLogging(s);
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.WARNING, "cannot determine whether '" + path + "' is a unified log format");
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the given path to find rotating log files.
|
||||
* @param path the path to the file
|
||||
*/
|
||||
public RotatingGCLogFile(Path path) {
|
||||
super(path, isUnifiedLogging(path));
|
||||
|
||||
if (getMetaData().isZip() || getMetaData().isGZip()) {
|
||||
//TODO: add code to ensure correct order to stream files in zip and gzip files
|
||||
this.orderedGarbageCollectionLogFiles = new LinkedList<>();
|
||||
} else {
|
||||
LinkedList<GarbageCollectionLogFileSegment> orderedSegments = null;
|
||||
try {
|
||||
List<GarbageCollectionLogFileSegment> segments = findGCLogSegments(path);
|
||||
orderedSegments = orderSegments(segments);
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.WARNING, "Cannot find and order GC log file segments for: " + path);
|
||||
} finally {
|
||||
this.orderedGarbageCollectionLogFiles = orderedSegments;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public RotatingGCLogFile(Path parentDirectory, List<GarbageCollectionLogFileSegment> segments) {
|
||||
super(parentDirectory, isUnifiedLogging(parentDirectory, segments));
|
||||
this.orderedGarbageCollectionLogFiles = orderSegments(segments);
|
||||
}
|
||||
|
||||
// suffix is like '.0' or '.5.current'
|
||||
private static final String ROTATING_LOG_SUFFIX = ".*(\\.\\d+(?:\\.current)?)$";
|
||||
|
||||
// given Path.getFileName().toString(), group(1) is the suffix of the rotating log.
|
||||
public static final Pattern ROTATING_LOG_PATTERN = Pattern.compile(ROTATING_LOG_SUFFIX);
|
||||
|
||||
private final LinkedList<GarbageCollectionLogFileSegment> orderedGarbageCollectionLogFiles;
|
||||
|
||||
@Override
|
||||
public Stream<String> stream() throws IOException {
|
||||
return stream(path, getMetaData(), orderedGarbageCollectionLogFiles);
|
||||
}
|
||||
|
||||
private static Stream<String> stream(
|
||||
Path path,
|
||||
FileDataSourceMetaData metadata,
|
||||
LinkedList<GarbageCollectionLogFileSegment> segments)
|
||||
throws IOException {
|
||||
//todo: find rolling files....
|
||||
if (metadata.isFile() || metadata.isDirectory()) {
|
||||
switch (segments.size()) {
|
||||
case 0:
|
||||
String[] empty = new String[0];
|
||||
return Arrays.stream(empty);
|
||||
case 1:
|
||||
return segments.getFirst().stream();
|
||||
default:
|
||||
// This code removes elements from the list of segments, so work on a copy.
|
||||
LinkedList<GarbageCollectionLogFileSegment> copySegments = new LinkedList<>(segments);
|
||||
Stream<String> allSegments = Stream.concat(copySegments.removeFirst().stream(), copySegments.removeFirst().stream());
|
||||
while (!copySegments.isEmpty())
|
||||
allSegments = Stream.concat(allSegments, copySegments.removeFirst().stream());
|
||||
return allSegments;
|
||||
}
|
||||
} else if (metadata.isZip()) {
|
||||
return streamZipFile(path);
|
||||
} else if (metadata.isGZip()) {
|
||||
throw new IOException("Unable to stream GZip files. Please unzip and retry");
|
||||
}
|
||||
throw new IOException("Unrecognised file type");
|
||||
}
|
||||
|
||||
private static Stream<String> streamZipFile(Path path) throws IOException {
|
||||
ZipFile zipFile = new ZipFile(path.toFile());
|
||||
List<ZipEntry> entries = zipFile.stream().filter(entry -> !entry.isDirectory()).collect(Collectors.toList());
|
||||
Vector<InputStream> streams = new Vector<>();
|
||||
try {
|
||||
entries
|
||||
.stream()
|
||||
.map(entry -> {
|
||||
try {
|
||||
return zipFile.getInputStream(entry);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
})
|
||||
.filter(Objects::nonNull)
|
||||
.forEach(streams::add);
|
||||
} catch (UncheckedIOException uioe) {
|
||||
throw uioe.getCause();
|
||||
}
|
||||
SequenceInputStream sequenceInputStream = new SequenceInputStream(streams.elements());
|
||||
return new BufferedReader(new InputStreamReader(sequenceInputStream)).lines();
|
||||
}
|
||||
|
||||
public List<GarbageCollectionLogFileSegment> getOrderedGarbageCollectionLogFiles() {
|
||||
return Collections.unmodifiableList(orderedGarbageCollectionLogFiles);
|
||||
}
|
||||
|
||||
//assume directory but then allow for a file.
|
||||
private static List<GarbageCollectionLogFileSegment> findGCLogSegments(Path path) throws IOException {
|
||||
|
||||
if (Files.isRegularFile(path)) {
|
||||
final String filename = path.getFileName().toString();
|
||||
final Matcher matcher = ROTATING_LOG_PATTERN.matcher(filename);
|
||||
final String rotatingLogBaseName;
|
||||
if (matcher.matches()) {
|
||||
String suffix = matcher.group(1);
|
||||
rotatingLogBaseName = filename.substring(0, filename.length()-suffix.length());
|
||||
} else {
|
||||
rotatingLogBaseName = filename;
|
||||
}
|
||||
Pattern rotatingLogBaseNamePattern = Pattern.compile(rotatingLogBaseName + "(?:" + ROTATING_LOG_SUFFIX + ")?");
|
||||
Predicate<Path> gcLogFragmentFinder = file -> rotatingLogBaseNamePattern.matcher(file.getFileName().toString()).matches();
|
||||
return Files.list(Paths.get(path.getParent().toString())).
|
||||
filter(Files::isRegularFile).
|
||||
filter(file -> !file.toFile().isHidden()).
|
||||
filter(gcLogFragmentFinder).
|
||||
map(GarbageCollectionLogFileSegment::new).
|
||||
collect(Collectors.toList());
|
||||
} else if (Files.isDirectory(path)) {
|
||||
return Files.list(path).
|
||||
filter(Files::isRegularFile).
|
||||
filter(file -> !file.toFile().isHidden()).
|
||||
map(GarbageCollectionLogFileSegment::new).
|
||||
collect(Collectors.toList());
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("path is not a file or directory: " + path);
|
||||
}
|
||||
|
||||
private static LinkedList<GarbageCollectionLogFileSegment> orderSegments(List<GarbageCollectionLogFileSegment> gcLogSegments) {
|
||||
|
||||
// Unified rotation: jdk11/src/hotspot/share/logging/logFileOutput.cpp
|
||||
// Output is always to named file, e.g. 'gc.log' if given -Xlog:gc*:file=gc.log::filecount=5
|
||||
// When gc.log is full, archive as gc.log.<_current_file>. Before the of gc.log to gc.log.<_current_file>,
|
||||
// an attempt is made to delete an existing gc.log.<_current_file>
|
||||
// Increment _current_file. if _current_file == filecount, set _current_file to zero
|
||||
// - JVM always begins archiving at gc.log.0
|
||||
// - gc.log is always the current log
|
||||
// - Once filecount files have been archived, archive begins at zero again
|
||||
//
|
||||
// Pre-unified rotation: jdk8/hotspot/src/share/vm/utilities/ostream.cpp
|
||||
// rotate file in names extended_filename.0, extended_filename.1, ...,
|
||||
// extended_filename.<NumberOfGCLogFiles - 1>. Current rotation file name will
|
||||
// have a form of extended_filename.<i>.current where i is the current rotation
|
||||
// file number. After it reaches max file size, the file will be saved and renamed
|
||||
// with .current removed from its tail.
|
||||
|
||||
if (gcLogSegments.size() < 2) {
|
||||
return new LinkedList<>(gcLogSegments);
|
||||
}
|
||||
|
||||
LinkedList<GarbageCollectionLogFileSegment> segments = new LinkedList<>();
|
||||
GarbageCollectionLogFileSegment[] orderedSegments = gcLogSegments.toArray(new GarbageCollectionLogFileSegment[0]);
|
||||
Arrays.sort(orderedSegments, Comparator.comparingInt(GarbageCollectionLogFileSegment::getSegmentIndex));
|
||||
|
||||
int current = orderedSegments.length;
|
||||
while (0 <= --current) {
|
||||
if (orderedSegments[current].isCurrent()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if current == -1, then there is no current! What to do?
|
||||
if (current == -1) {
|
||||
Collections.addAll(segments, orderedSegments);
|
||||
return segments;
|
||||
}
|
||||
|
||||
double closestTime = Double.MAX_VALUE;
|
||||
// Find where current belongs.
|
||||
for (int index = current-1; 0 <= index; --index) {
|
||||
double delta = GarbageCollectionLogFileSegment.rolloverDelta(orderedSegments[current], orderedSegments[index]);
|
||||
if (!Double.isNaN(delta) && 0 <= delta && delta < closestTime) {
|
||||
GarbageCollectionLogFileSegment temp = orderedSegments[current];
|
||||
for(int n=current; n > index+1; --n) {
|
||||
orderedSegments[n] = orderedSegments[n-1];
|
||||
}
|
||||
orderedSegments[current=index+1] = temp;
|
||||
closestTime = delta;
|
||||
}
|
||||
}
|
||||
|
||||
segments.addLast(orderedSegments[current]);
|
||||
|
||||
int index = ((current-1) + orderedSegments.length) % orderedSegments.length;
|
||||
while (index != current) {
|
||||
if (orderedSegments[current].isContiguousWith(orderedSegments[index])) {
|
||||
segments.addFirst(orderedSegments[index]);
|
||||
current = index;
|
||||
index = ((current - 1) + orderedSegments.length) % orderedSegments.length;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return segments;
|
||||
}
|
||||
}
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче