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 > committed</tt> even 75 * if <tt>used <= 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 StringBuilder sb = new StringBuilder(); 241 sb.append("init = ").append(init).append('(').append(init >> 10) 242 .append("K) "); 243 sb.append("used = ").append(used).append('(').append(used >> 10) 244 .append("K) "); 245 sb.append("committed = ").append(committed).append('(') 246 .append(committed >> 10).append("K) "); 247 sb.append("max = ").append(max).append('(').append(max >> 10) 248 .append("K)"); 249 return sb.toString(); 250 } 251 252 /** 253 * Returns a <tt>MemoryUsage</tt> object represented by the 254 * given <tt>CompositeData</tt>. The given <tt>CompositeData</tt> 255 * must contain the following attributes: 256 * 257 * <blockquote> 258 * <table border summary="The attributes and the types the given CompositeData contains"> 259 * <tr> 260 * <th align=left>Attribute Name</th> 261 * <th align=left>Type</th> 262 * </tr> 263 * <tr> 264 * <td>init</td> 265 * <td><tt>java.lang.Long</tt></td> 266 * </tr> 267 * <tr> 268 * <td>used</td> 269 * <td><tt>java.lang.Long</tt></td> 270 * </tr> 271 * <tr> 272 * <td>committed</td> 273 * <td><tt>java.lang.Long</tt></td> 274 * </tr> 275 * <tr> 276 * <td>max</td> 277 * <td><tt>java.lang.Long</tt></td> 278 * </tr> 279 * </table> 280 * </blockquote> 281 * 282 * @param cd <tt>CompositeData</tt> representing a <tt>MemoryUsage</tt> 283 * 284 * @throws IllegalArgumentException if <tt>cd</tt> does not 285 * represent a <tt>MemoryUsage</tt> with the attributes described 286 * above. 287 * 288 * @return a <tt>MemoryUsage</tt> object represented by <tt>cd</tt> 289 * if <tt>cd</tt> is not <tt>null</tt>; 290 * <tt>null</tt> otherwise. 291 */ 292 public static MemoryUsage from(CompositeData cd) { 293 if (cd == null) { 294 return null; 295 } 296 297 if (cd instanceof MemoryUsageCompositeData) { 298 return ((MemoryUsageCompositeData) cd).getMemoryUsage(); 299 } else { 300 return new MemoryUsage(cd); 301 } 302 303 } 304 }