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