1 /*
2  * Copyright (c) 2003, 2019, 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  * <h2>MXBean Mapping</h2>
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 
GcInfo(GcInfoBuilder builder, long index, long startTime, long endTime, MemoryUsage[] muBeforeGc, MemoryUsage[] muAfterGc, Object[] extAttributes)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 
GcInfo(CompositeData cd)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      */
getId()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      */
getStartTime()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      */
getEndTime()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      */
getDuration()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      */
getMemoryUsageBeforeGc()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      */
getMemoryUsageAfterGc()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      */
from(CompositeData cd)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
containsKey(String key)239     public boolean containsKey(String key) {
240         return cdata.containsKey(key);
241     }
242 
containsValue(Object value)243     public boolean containsValue(Object value) {
244         return cdata.containsValue(value);
245     }
246 
equals(Object obj)247     public boolean equals(Object obj) {
248         return cdata.equals(obj);
249     }
250 
get(String key)251     public Object get(String key) {
252         return cdata.get(key);
253     }
254 
getAll(String[] keys)255     public Object[] getAll(String[] keys) {
256         return cdata.getAll(keys);
257     }
258 
getCompositeType()259     public CompositeType getCompositeType() {
260         return cdata.getCompositeType();
261     }
262 
hashCode()263     public int hashCode() {
264         return cdata.hashCode();
265     }
266 
toString()267     public String toString() {
268         return cdata.toString();
269     }
270 
values()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      */
toCompositeData(CompositeType ct)287     public CompositeData toCompositeData(CompositeType ct) {
288         return cdata;
289     }
290 }
291