All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.airlift.stats.GarbageCollectionNotificationInfo Maven / Gradle / Ivy

package com.facebook.airlift.stats;

import com.google.common.collect.ImmutableMap;
import io.airlift.units.DataSize;

import javax.management.openmbean.CompositeData;
import javax.management.openmbean.TabularData;

import java.lang.management.MemoryUsage;
import java.util.Collection;
import java.util.Map;

import static com.google.common.base.MoreObjects.toStringHelper;
import static io.airlift.units.DataSize.succinctBytes;
import static java.lang.Math.max;
import static java.util.Objects.requireNonNull;

public class GarbageCollectionNotificationInfo
{
    // these are well known constants used by all known OpenJDK GCs
    private static final String MINOR_GC_NAME = "end of minor GC";
    private static final String MAJOR_GC_NAME = "end of major GC";

    private final String gcName;
    private final String gcAction;
    private final String gcCause;

    private final long startTime;
    private final long endTime;
    private final Map usageBeforeGc;
    private final Map usageAfterGc;

    public GarbageCollectionNotificationInfo(CompositeData compositeData)
    {
        requireNonNull(compositeData, "compositeData is null");
        this.gcName = (String) compositeData.get("gcName");
        this.gcAction = (String) compositeData.get("gcAction");
        this.gcCause = (String) compositeData.get("gcCause");

        CompositeData gcInfo = (CompositeData) compositeData.get("gcInfo");
        this.startTime = (Long) gcInfo.get("startTime");
        this.endTime = (Long) gcInfo.get("endTime");
        this.usageBeforeGc = extractMemoryUsageMap(gcInfo, "memoryUsageBeforeGc");
        this.usageAfterGc = extractMemoryUsageMap(gcInfo, "memoryUsageAfterGc");
    }

    public long getStartTime()
    {
        return startTime;
    }

    public long getEndTime()
    {
        return endTime;
    }

    public long getDurationMs()
    {
        return max(0, this.endTime - this.startTime);
    }

    public Map getMemoryUsageBeforeGc()
    {
        return usageBeforeGc;
    }

    public Map getMemoryUsageAfterGc()
    {
        return usageAfterGc;
    }

    public DataSize getBeforeGcTotal()
    {
        return totalMemorySize(getMemoryUsageBeforeGc());
    }

    public DataSize getAfterGcTotal()
    {
        return totalMemorySize(getMemoryUsageAfterGc());
    }

    public boolean isMinorGc()
    {
        return gcAction.equalsIgnoreCase(MINOR_GC_NAME);
    }

    public boolean isMajorGc()
    {
        return gcAction.equalsIgnoreCase(MAJOR_GC_NAME);
    }

    @Override
    public String toString()
    {
        return toStringHelper(this)
                .add("gcName", gcName)
                .add("gcAction", gcAction)
                .add("gcCause", gcCause)
                .add("durationMs", getDurationMs())
                .add("beforeGcMb", getBeforeGcTotal())
                .add("afterGcMb", getAfterGcTotal())
                .toString();
    }

    private static DataSize totalMemorySize(Map memUsages)
    {
        long bytes = 0;
        for (MemoryUsage memoryUsage : memUsages.values()) {
            bytes += memoryUsage.getUsed();
        }
        return succinctBytes(bytes);
    }

    private static Map extractMemoryUsageMap(CompositeData compositeData, String attributeName)
    {
        ImmutableMap.Builder map = ImmutableMap.builder();
        TabularData tabularData = (TabularData) compositeData.get(attributeName);
        for (CompositeData entry : (Collection) tabularData.values()) {
            map.put((String) entry.get("key"), MemoryUsage.from((CompositeData) entry.get("value")));
        }
        return map.build();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy