1 /*
   2  * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.management;
  27 
  28 import java.lang.management.MemoryUsage;
  29 import javax.management.openmbean.CompositeData;
  30 import javax.management.openmbean.CompositeDataView;
  31 import javax.management.openmbean.CompositeType;
  32 import java.util.Collection;
  33 import java.util.Collections;
  34 import java.util.HashMap;
  35 import java.util.Map;
  36 import com.sun.management.internal.GcInfoCompositeData;
  37 import com.sun.management.internal.GcInfoBuilder;
  38 
  39 /**
  40  * Garbage collection information.  It contains the following
  41  * information for one garbage collection as well as GC-specific
  42  * attributes:
  43  * <blockquote>
  44  * <ul>
  45  *   <li>Start time</li>
  46  *   <li>End time</li>
  47  *   <li>Duration</li>
  48  *   <li>Memory usage before the collection starts</li>
  49  *   <li>Memory usage after the collection ends</li>
  50  * </ul>
  51  * </blockquote>
  52  *
  53  * <p>
  54  * {@code GcInfo} is a {@link CompositeData CompositeData}
  55  * The GC-specific attributes can be obtained via the CompositeData
  56  * interface.  This is a historical relic, and other classes should
  57  * not copy this pattern.  Use {@link CompositeDataView} instead.
  58  *
  59  * <h3>MXBean Mapping</h3>
  60  * {@code GcInfo} is mapped to a {@link CompositeData CompositeData}
  61  * with attributes as specified in the {@link #from from} method.
  62  *
  63  * @author  Mandy Chung
  64  * @since   1.5
  65  */
  66 public class GcInfo implements CompositeData, CompositeDataView {
  67     private final long index;
  68     private final long startTime;
  69     private final long endTime;
  70     private final Map<String, MemoryUsage> usageBeforeGc;
  71     private final Map<String, MemoryUsage> usageAfterGc;
  72     private final Object[] extAttributes;
  73     private final CompositeData cdata;
  74     private final GcInfoBuilder builder;
  75 
  76     private GcInfo(GcInfoBuilder builder,
  77                    long index, long startTime, long endTime,
  78                    MemoryUsage[] muBeforeGc,
  79                    MemoryUsage[] muAfterGc,
  80                    Object[] extAttributes) {
  81         this.builder       = builder;
  82         this.index         = index;
  83         this.startTime     = startTime;
  84         this.endTime       = endTime;
  85         String[] poolNames = builder.getPoolNames();
  86         this.usageBeforeGc = new HashMap<String, MemoryUsage>(poolNames.length);
  87         this.usageAfterGc = new HashMap<String, MemoryUsage>(poolNames.length);
  88         for (int i = 0; i < poolNames.length; i++) {
  89             this.usageBeforeGc.put(poolNames[i],  muBeforeGc[i]);
  90             this.usageAfterGc.put(poolNames[i],  muAfterGc[i]);
  91         }
  92         this.extAttributes = extAttributes;
  93         this.cdata = new GcInfoCompositeData(this, builder, extAttributes);
  94     }
  95 
  96     private GcInfo(CompositeData cd) {
  97         GcInfoCompositeData.validateCompositeData(cd);
  98 
  99         this.index         = GcInfoCompositeData.getId(cd);
 100         this.startTime     = GcInfoCompositeData.getStartTime(cd);
 101         this.endTime       = GcInfoCompositeData.getEndTime(cd);
 102         this.usageBeforeGc = GcInfoCompositeData.getMemoryUsageBeforeGc(cd);
 103         this.usageAfterGc  = GcInfoCompositeData.getMemoryUsageAfterGc(cd);
 104         this.extAttributes = null;
 105         this.builder       = null;
 106         this.cdata         = cd;
 107     }
 108 
 109     /**
 110      * Returns the identifier of this garbage collection which is
 111      * the number of collections that this collector has done.
 112      *
 113      * @return the identifier of this garbage collection which is
 114      * the number of collections that this collector has done.
 115      */
 116     public long getId() {
 117         return index;
 118     }
 119 
 120     /**
 121      * Returns the start time of this GC in milliseconds
 122      * since the Java virtual machine was started.
 123      *
 124      * @return the start time of this GC.
 125      */
 126     public long getStartTime() {
 127         return startTime;
 128     }
 129 
 130     /**
 131      * Returns the end time of this GC in milliseconds
 132      * since the Java virtual machine was started.
 133      *
 134      * @return the end time of this GC.
 135      */
 136     public long getEndTime() {
 137         return endTime;
 138     }
 139 
 140     /**
 141      * Returns the elapsed time of this GC in milliseconds.
 142      *
 143      * @return the elapsed time of this GC in milliseconds.
 144      */
 145     public long getDuration() {
 146         return endTime - startTime;
 147     }
 148 
 149     /**
 150      * Returns the memory usage of all memory pools
 151      * at the beginning of this GC.
 152      * This method returns
 153      * a {@code Map} of the name of a memory pool
 154      * to the memory usage of the corresponding
 155      * memory pool before GC starts.
 156      *
 157      * @return a {@code Map} of memory pool names to the memory
 158      * usage of a memory pool before GC starts.
 159      */
 160     public Map<String, MemoryUsage> getMemoryUsageBeforeGc() {
 161         return Collections.unmodifiableMap(usageBeforeGc);
 162     }
 163 
 164     /**
 165      * Returns the memory usage of all memory pools
 166      * at the end of this GC.
 167      * This method returns
 168      * a {@code Map} of the name of a memory pool
 169      * to the memory usage of the corresponding
 170      * memory pool when GC finishes.
 171      *
 172      * @return a {@code Map} of memory pool names to the memory
 173      * usage of a memory pool when GC finishes.
 174      */
 175     public Map<String, MemoryUsage> getMemoryUsageAfterGc() {
 176         return Collections.unmodifiableMap(usageAfterGc);
 177     }
 178 
 179    /**
 180      * Returns a {@code GcInfo} object represented by the
 181      * given {@code CompositeData}. The given
 182      * {@code CompositeData} must contain
 183      * all the following attributes:
 184      *
 185      * <blockquote>
 186      * <table class="striped"><caption style="display:none">description</caption>
 187      * <thead>
 188      * <tr>
 189      *   <th scope="col" style="text-align:left">Attribute Name</th>
 190      *   <th scope="col" style="text-align:left">Type</th>
 191      * </tr>
 192      * </thead>
 193      * <tbody>
 194      * <tr>
 195      *   <th scope="row">index</th>
 196      *   <td>{@code java.lang.Long}</td>
 197      * </tr>
 198      * <tr>
 199      *   <th scope="row">startTime</th>
 200      *   <td>{@code java.lang.Long}</td>
 201      * </tr>
 202      * <tr>
 203      *   <th scope="row">endTime</th>
 204      *   <td>{@code java.lang.Long}</td>
 205      * </tr>
 206      * <tr>
 207      *   <th scope="row">memoryUsageBeforeGc</th>
 208      *   <td>{@code javax.management.openmbean.TabularData}</td>
 209      * </tr>
 210      * <tr>
 211      *   <th scope="row">memoryUsageAfterGc</th>
 212      *   <td>{@code javax.management.openmbean.TabularData}</td>
 213      * </tr>
 214      * </tbody>
 215      * </table>
 216      * </blockquote>
 217      *
 218      * @throws IllegalArgumentException if {@code cd} does not
 219      *   represent a {@code GcInfo} object with the attributes
 220      *   described above.
 221      *
 222      * @return a {@code GcInfo} object represented by {@code cd}
 223      * if {@code cd} is not {@code null}; {@code null} otherwise.
 224      */
 225     public static GcInfo from(CompositeData cd) {
 226         if (cd == null) {
 227             return null;
 228         }
 229 
 230         if (cd instanceof GcInfoCompositeData) {
 231             return ((GcInfoCompositeData) cd).getGcInfo();
 232         } else {
 233             return new GcInfo(cd);
 234         }
 235 
 236     }
 237 
 238     // Implementation of the CompositeData interface
 239     public boolean containsKey(String key) {
 240         return cdata.containsKey(key);
 241     }
 242 
 243     public boolean containsValue(Object value) {
 244         return cdata.containsValue(value);
 245     }
 246 
 247     public boolean equals(Object obj) {
 248         return cdata.equals(obj);
 249     }
 250 
 251     public Object get(String key) {
 252         return cdata.get(key);
 253     }
 254 
 255     public Object[] getAll(String[] keys) {
 256         return cdata.getAll(keys);
 257     }
 258 
 259     public CompositeType getCompositeType() {
 260         return cdata.getCompositeType();
 261     }
 262 
 263     public int hashCode() {
 264         return cdata.hashCode();
 265     }
 266 
 267     public String toString() {
 268         return cdata.toString();
 269     }
 270 
 271     public Collection<?> values() {
 272         return cdata.values();
 273     }
 274 
 275     /**
 276      * Return the {@code CompositeData} representation of this
 277      * {@code GcInfo}, including any GC-specific attributes.  The
 278      * returned value will have at least all the attributes described
 279      * in the {@link #from(CompositeData) from} method, plus optionally
 280      * other attributes.
 281      *
 282      * @param ct the {@code CompositeType} that the caller expects.
 283      * This parameter is ignored and can be null.
 284      *
 285      * @return the {@code CompositeData} representation.
 286      */
 287     public CompositeData toCompositeData(CompositeType ct) {
 288         return cdata;
 289     }
 290 }