1 /*
2  * Copyright (c) 2003, 2013, 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 java.lang.management;
27 
28 import javax.management.openmbean.CompositeData;
29 import sun.management.MemoryUsageCompositeData;
30 
31 /**
32  * A <tt>MemoryUsage</tt> object represents a snapshot of memory usage.
33  * Instances of the <tt>MemoryUsage</tt> class are usually constructed
34  * by methods that are used to obtain memory usage
35  * information about individual memory pool of the Java virtual machine or
36  * the heap or non-heap memory of the Java virtual machine as a whole.
37  *
38  * <p> A <tt>MemoryUsage</tt> object contains four values:
39  * <table summary="Describes the MemoryUsage object content">
40  * <tr>
41  * <td valign=top> <tt>init</tt> </td>
42  * <td valign=top> represents the initial amount of memory (in bytes) that
43  *      the Java virtual machine requests from the operating system
44  *      for memory management during startup.  The Java virtual machine
45  *      may request additional memory from the operating system and
46  *      may also release memory to the system over time.
47  *      The value of <tt>init</tt> may be undefined.
48  * </td>
49  * </tr>
50  * <tr>
51  * <td valign=top> <tt>used</tt> </td>
52  * <td valign=top> represents the amount of memory currently used (in bytes).
53  * </td>
54  * </tr>
55  * <tr>
56  * <td valign=top> <tt>committed</tt> </td>
57  * <td valign=top> represents the amount of memory (in bytes) that is
58  *      guaranteed to be available for use by the Java virtual machine.
59  *      The amount of committed memory may change over time (increase
60  *      or decrease).  The Java virtual machine may release memory to
61  *      the system and <tt>committed</tt> could be less than <tt>init</tt>.
62  *      <tt>committed</tt> will always be greater than
63  *      or equal to <tt>used</tt>.
64  * </td>
65  * </tr>
66  * <tr>
67  * <td valign=top> <tt>max</tt> </td>
68  * <td valign=top> represents the maximum amount of memory (in bytes)
69  *      that can be used for memory management. Its value may be undefined.
70  *      The maximum amount of memory may change over time if defined.
71  *      The amount of used and committed memory will always be less than
72  *      or equal to <tt>max</tt> if <tt>max</tt> is defined.
73  *      A memory allocation may fail if it attempts to increase the
74  *      used memory such that <tt>used &gt; committed</tt> even
75  *      if <tt>used &lt;= max</tt> would still be true (for example,
76  *      when the system is low on virtual memory).
77  * </td>
78  * </tr>
79  * </table>
80  *
81  * Below is a picture showing an example of a memory pool:
82  *
83  * <pre>
84  *        +----------------------------------------------+
85  *        +////////////////           |                  +
86  *        +////////////////           |                  +
87  *        +----------------------------------------------+
88  *
89  *        |--------|
90  *           init
91  *        |---------------|
92  *               used
93  *        |---------------------------|
94  *                  committed
95  *        |----------------------------------------------|
96  *                            max
97  * </pre>
98  *
99  * <h3>MXBean Mapping</h3>
100  * <tt>MemoryUsage</tt> is mapped to a {@link CompositeData CompositeData}
101  * with attributes as specified in the {@link #from from} method.
102  *
103  * @author   Mandy Chung
104  * @since   1.5
105  */
106 public class MemoryUsage {
107     private final long init;
108     private final long used;
109     private final long committed;
110     private final long max;
111 
112     /**
113      * Constructs a <tt>MemoryUsage</tt> object.
114      *
115      * @param init      the initial amount of memory in bytes that
116      *                  the Java virtual machine allocates;
117      *                  or <tt>-1</tt> if undefined.
118      * @param used      the amount of used memory in bytes.
119      * @param committed the amount of committed memory in bytes.
120      * @param max       the maximum amount of memory in bytes that
121      *                  can be used; or <tt>-1</tt> if undefined.
122      *
123      * @throws IllegalArgumentException if
124      * <ul>
125      * <li> the value of <tt>init</tt> or <tt>max</tt> is negative
126      *      but not <tt>-1</tt>; or</li>
127      * <li> the value of <tt>used</tt> or <tt>committed</tt> is negative;
128      *      or</li>
129      * <li> <tt>used</tt> is greater than the value of <tt>committed</tt>;
130      *      or</li>
131      * <li> <tt>committed</tt> is greater than the value of <tt>max</tt>
132      *      <tt>max</tt> if defined.</li>
133      * </ul>
134      */
MemoryUsage(long init, long used, long committed, long max)135     public MemoryUsage(long init,
136                        long used,
137                        long committed,
138                        long max) {
139         if (init < -1) {
140             throw new IllegalArgumentException( "init parameter = " +
141                 init + " is negative but not -1.");
142         }
143         if (max < -1) {
144             throw new IllegalArgumentException( "max parameter = " +
145                 max + " is negative but not -1.");
146         }
147         if (used < 0) {
148             throw new IllegalArgumentException( "used parameter = " +
149                 used + " is negative.");
150         }
151         if (committed < 0) {
152             throw new IllegalArgumentException( "committed parameter = " +
153                 committed + " is negative.");
154         }
155         if (used > committed) {
156             throw new IllegalArgumentException( "used = " + used +
157                 " should be <= committed = " + committed);
158         }
159         if (max >= 0 && committed > max) {
160             throw new IllegalArgumentException( "committed = " + committed +
161                 " should be < max = " + max);
162         }
163 
164         this.init = init;
165         this.used = used;
166         this.committed = committed;
167         this.max = max;
168     }
169 
170     /**
171      * Constructs a <tt>MemoryUsage</tt> object from a
172      * {@link CompositeData CompositeData}.
173      */
MemoryUsage(CompositeData cd)174     private MemoryUsage(CompositeData cd) {
175         // validate the input composite data
176         MemoryUsageCompositeData.validateCompositeData(cd);
177 
178         this.init = MemoryUsageCompositeData.getInit(cd);
179         this.used = MemoryUsageCompositeData.getUsed(cd);
180         this.committed = MemoryUsageCompositeData.getCommitted(cd);
181         this.max = MemoryUsageCompositeData.getMax(cd);
182     }
183 
184     /**
185      * Returns the amount of memory in bytes that the Java virtual machine
186      * initially requests from the operating system for memory management.
187      * This method returns <tt>-1</tt> if the initial memory size is undefined.
188      *
189      * @return the initial size of memory in bytes;
190      * <tt>-1</tt> if undefined.
191      */
getInit()192     public long getInit() {
193         return init;
194     }
195 
196     /**
197      * Returns the amount of used memory in bytes.
198      *
199      * @return the amount of used memory in bytes.
200      *
201      */
getUsed()202     public long getUsed() {
203         return used;
204     };
205 
206     /**
207      * Returns the amount of memory in bytes that is committed for
208      * the Java virtual machine to use.  This amount of memory is
209      * guaranteed for the Java virtual machine to use.
210      *
211      * @return the amount of committed memory in bytes.
212      *
213      */
getCommitted()214     public long getCommitted() {
215         return committed;
216     };
217 
218     /**
219      * Returns the maximum amount of memory in bytes that can be
220      * used for memory management.  This method returns <tt>-1</tt>
221      * if the maximum memory size is undefined.
222      *
223      * <p> This amount of memory is not guaranteed to be available
224      * for memory management if it is greater than the amount of
225      * committed memory.  The Java virtual machine may fail to allocate
226      * memory even if the amount of used memory does not exceed this
227      * maximum size.
228      *
229      * @return the maximum amount of memory in bytes;
230      * <tt>-1</tt> if undefined.
231      */
getMax()232     public long getMax() {
233         return max;
234     };
235 
236     /**
237      * Returns a descriptive representation of this memory usage.
238      */
toString()239     public String toString() {
240         StringBuffer buf = new StringBuffer();
241         buf.append("init = " + init + "(" + (init >> 10) + "K) ");
242         buf.append("used = " + used + "(" + (used >> 10) + "K) ");
243         buf.append("committed = " + committed + "(" +
244                    (committed >> 10) + "K) " );
245         buf.append("max = " + max + "(" + (max >> 10) + "K)");
246         return buf.toString();
247     }
248 
249     /**
250      * Returns a <tt>MemoryUsage</tt> object represented by the
251      * given <tt>CompositeData</tt>. The given <tt>CompositeData</tt>
252      * must contain the following attributes:
253      *
254      * <blockquote>
255      * <table border summary="The attributes and the types the given CompositeData contains">
256      * <tr>
257      *   <th align=left>Attribute Name</th>
258      *   <th align=left>Type</th>
259      * </tr>
260      * <tr>
261      *   <td>init</td>
262      *   <td><tt>java.lang.Long</tt></td>
263      * </tr>
264      * <tr>
265      *   <td>used</td>
266      *   <td><tt>java.lang.Long</tt></td>
267      * </tr>
268      * <tr>
269      *   <td>committed</td>
270      *   <td><tt>java.lang.Long</tt></td>
271      * </tr>
272      * <tr>
273      *   <td>max</td>
274      *   <td><tt>java.lang.Long</tt></td>
275      * </tr>
276      * </table>
277      * </blockquote>
278      *
279      * @param cd <tt>CompositeData</tt> representing a <tt>MemoryUsage</tt>
280      *
281      * @throws IllegalArgumentException if <tt>cd</tt> does not
282      *   represent a <tt>MemoryUsage</tt> with the attributes described
283      *   above.
284      *
285      * @return a <tt>MemoryUsage</tt> object represented by <tt>cd</tt>
286      *         if <tt>cd</tt> is not <tt>null</tt>;
287      *         <tt>null</tt> otherwise.
288      */
from(CompositeData cd)289     public static MemoryUsage from(CompositeData cd) {
290         if (cd == null) {
291             return null;
292         }
293 
294         if (cd instanceof MemoryUsageCompositeData) {
295             return ((MemoryUsageCompositeData) cd).getMemoryUsage();
296         } else {
297             return new MemoryUsage(cd);
298         }
299 
300     }
301 }
302