View Javadoc
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      */
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      */
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      */
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      */
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      */
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      */
232     public long getMax() {
233         return max;
234     };
235 
236     /**
237      * Returns a descriptive representation of this memory usage.
238      */
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      */
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 }