001 /* 002 * Copyright 2008-2015 UnboundID Corp. 003 * All Rights Reserved. 004 */ 005 /* 006 * Copyright (C) 2015 UnboundID Corp. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021 package com.unboundid.ldap.sdk.unboundidds.monitors; 022 023 024 025 import java.util.ArrayList; 026 import java.util.Collections; 027 import java.util.LinkedHashMap; 028 import java.util.List; 029 import java.util.Map; 030 import java.util.TreeMap; 031 import java.util.TreeSet; 032 033 import com.unboundid.ldap.sdk.Attribute; 034 import com.unboundid.ldap.sdk.Entry; 035 import com.unboundid.util.NotMutable; 036 import com.unboundid.util.ThreadSafety; 037 import com.unboundid.util.ThreadSafetyLevel; 038 039 import static com.unboundid.ldap.sdk.unboundidds.monitors.MonitorMessages.*; 040 import static com.unboundid.util.Debug.*; 041 import static com.unboundid.util.StaticUtils.*; 042 043 044 045 /** 046 * <BLOCKQUOTE> 047 * <B>NOTE:</B> This class is part of the Commercial Edition of the UnboundID 048 * LDAP SDK for Java. It is not available for use in applications that 049 * include only the Standard Edition of the LDAP SDK, and is not supported for 050 * use in conjunction with non-UnboundID products. 051 * </BLOCKQUOTE> 052 * This class defines a monitor entry that provides information about the memory 053 * usage for the JVM in which the Directory Server is running. In particular, 054 * it reports information about the memory pools and garbage collectors defined 055 * in the JVM. The information that may be available in the memory usage 056 * monitor entry includes: 057 * <UL> 058 * <LI>The names of the memory pools that are in use within the JVM.</LI> 059 * <LI>The number of bytes currently used within each memory pool.</LI> 060 * <LI>The number of bytes used within each memory pool after the last 061 * garbage collection.</LI> 062 * <LI>The names of the garbage collectors that are in use within the 063 * JVM.</LI> 064 * <LI>The number of garbage collections performed by each collector.</LI> 065 * <LI>The total duration of all garbage collections performed by each 066 * collector.</LI> 067 * <LI>The average duration of garbage collections performed by each 068 * collector.</LI> 069 * <LI>The duration of the most recent garbage collection performed by each 070 * collector.</LI> 071 * <LI>The amount of non-heap memory consumed by the JVM.</LI> 072 * <LI>The number of detected pauses of various durations detected by the 073 * server.</LI> 074 * <LI>The duration of the longest pause detected by the server.</LI> 075 * </UL> 076 * The server should present at most one memory usage monitor entry. It can be 077 * retrieved using the {@link MonitorManager#getMemoryUsageMonitorEntry} method. 078 * This entry provides specific methods for accessing information about JVM 079 * memory usage (e.g., the {@link MemoryUsageMonitorEntry#getMemoryPoolNames} 080 * method can be used to retrieve the names of the memory pool). Alternately, 081 * this information may be accessed using the generic API. See the 082 * {@link MonitorManager} class documentation for an example that demonstrates 083 * the use of the generic API for accessing monitor data. 084 */ 085 @NotMutable() 086 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 087 public final class MemoryUsageMonitorEntry 088 extends MonitorEntry 089 { 090 /** 091 * The structural object class used in memory usage monitor entries. 092 */ 093 static final String MEMORY_USAGE_MONITOR_OC = 094 "ds-memory-usage-monitor-entry"; 095 096 097 098 /** 099 * The name of the attribute that holds the duration of the longest detected 100 * pause. 101 */ 102 private static final String ATTR_LONGEST_PAUSE_TIME = 103 "max-detected-pause-time-millis"; 104 105 106 107 /** 108 * The name of the attribute that holds the amount of non-heap memory used 109 * by the JVM. 110 */ 111 private static final String ATTR_NON_HEAP_USED = "non-heap-memory-bytes-used"; 112 113 114 115 /** 116 * The name of the attribute that holds the total amount of memory used by 117 * memory consumers. 118 */ 119 private static final String ATTR_TOTAL_CONSUMER_MEMORY = 120 "total-bytes-used-by-memory-consumers"; 121 122 123 124 /** 125 * The name of the attribute that holds the percentage of committed tenured 126 * memory held by memory consumers. 127 */ 128 private static final String ATTR_TOTAL_CONSUMER_MEMORY_AS_PCT_OF_COMMITTED = 129 "memory-consumers-total-as-percent-of-committed-tenured-memory"; 130 131 132 133 /** 134 * The name of the attribute that holds the percentage of maximum allowed 135 * tenured memory held by memory consumers. 136 */ 137 private static final String ATTR_TOTAL_CONSUMER_MEMORY_AS_PCT_OF_MAX = 138 "memory-consumers-total-as-percent-of-maximum-tenured-memory"; 139 140 141 142 /** 143 * The prefix that will be used for pauses detected by the server. 144 */ 145 private static final String ATTR_PREFIX_DETECTED_PAUSE = 146 "detected-pauses-over-"; 147 148 149 150 /** 151 * The suffix that will be used for attributes providing the total collection 152 * count for a garbage collector. 153 */ 154 private static final String ATTR_SUFFIX_TOTAL_COLLECTION_COUNT = 155 "-total-collection-count"; 156 157 158 159 /** 160 * The suffix that will be used for attributes providing the total collection 161 * duration for a garbage collector. 162 */ 163 private static final String ATTR_SUFFIX_TOTAL_COLLECTION_DURATION = 164 "-total-collection-duration"; 165 166 167 168 /** 169 * The suffix that will be used for attributes providing the average 170 * collection duration for a garbage collector. 171 */ 172 private static final String ATTR_SUFFIX_AVERAGE_COLLECTION_DURATION = 173 "-average-collection-duration"; 174 175 176 177 /** 178 * The suffix that will be used for attributes providing the recent collection 179 * duration for a garbage collector. 180 */ 181 private static final String ATTR_SUFFIX_RECENT_COLLECTION_DURATION = 182 "-recent-collection-duration"; 183 184 185 186 /** 187 * The suffix that will be used for attributes providing the current bytes 188 * used in a memory pool. 189 */ 190 private static final String ATTR_SUFFIX_CURRENT_BYTES_USED = 191 "-current-bytes-used"; 192 193 194 195 /** 196 * The suffix that will be used for attributes providing the bytes used after 197 * the last collection in a memory pool. 198 */ 199 private static final String ATTR_SUFFIX_BYTES_USED_AFTER_LAST_COLLECTION = 200 "-bytes-used-after-last-collection"; 201 202 203 204 /** 205 * The name of the property used to provide the numbers of pauses of various 206 * durations detected. 207 */ 208 private static final String PROPERTY_DETECTED_PAUSE_COUNTS = 209 "detected-pause-counts"; 210 211 212 213 /** 214 * The name of the attribute that holds the maximum amount of memory that may 215 * be used by the JVM, in megabytes. 216 */ 217 private static final String ATTR_MAX_RESERVABLE_MEMORY_MB = 218 "maxReservableMemoryMB"; 219 220 221 222 /** 223 * The name of the attribute that holds the amount of memory currently 224 * allocated for use by the JVM, in megabytes. 225 */ 226 private static final String ATTR_CURRENT_RESERVED_MEMORY_MB = 227 "currentReservedMemoryMB"; 228 229 230 231 /** 232 * The name of the attribute that holds the amount of allocated JVM memory 233 * which is actually in use. 234 */ 235 private static final String ATTR_USED_MEMORY_MB = "usedReservedMemoryMB"; 236 237 238 239 /** 240 * The name of the attribute that holds the amount of allocated JVM memory 241 * that is not currently in use. 242 */ 243 private static final String ATTR_FREE_MEMORY_MB = "freeReservedMemoryMB"; 244 245 246 247 /** 248 * The name of the attribute that holds the percentage of the maximum JVM 249 * memory that is actually in use. 250 */ 251 private static final String ATTR_RESERVED_MEMORY_PERCENT_FULL = 252 "reservedMemoryPercentFull"; 253 254 255 256 /** 257 * The serial version UID for this serializable class. 258 */ 259 private static final long serialVersionUID = 1924052253885937441L; 260 261 262 263 // The list of garbage collectors for which information is available. 264 private final List<String> garbageCollectors; 265 266 // The list of memory pools for which information is available. 267 private final List<String> memoryPools; 268 269 // The amount of memory that has currently been allocated by the JVM, in 270 // megabytes. 271 private final Long currentReservedMemoryMB; 272 273 // The amount of allocated JVM memory that is not currently in use, in 274 // megabytes. 275 private final Long freeReservedMemoryMB; 276 277 // The maximum pause time detected by the JVM. 278 private final Long maxDetectedPauseTime; 279 280 // The maximum amount of memory that may be used by the JVM, in megabytes. 281 private final Long maxReservableMemoryMB; 282 283 // The amount of non-heap memory consumed by the JVM. 284 private final Long nonHeapMemoryUsed; 285 286 // The percentage of committed tenured memory held by consumers. 287 private final Long percentOfCommittedTenuredMemory; 288 289 // The percentage of maximum tenured memory held by consumers. 290 private final Long percentOfMaxTenuredMemory; 291 292 // The percentage of the maximum JVM memory that is currently in use. 293 private final Long reservedMemoryPercentFull; 294 295 // The total amount of memory held by memory consumers. 296 private final Long totalBytesHeldByConsumers; 297 298 // The amount of allocated JVM memory that is currently in use, in megabytes. 299 private final Long usedReservedMemoryMB; 300 301 // The number of pauses exceeding specified thresholds. 302 private final Map<Long,Long> detectedPauses; 303 304 // The list of bytes used after the last collection per memory pool. 305 private final Map<String,Long> bytesUsedAfterLastCollectionPerMP; 306 307 // The list of current bytes used per memory pool. 308 private final Map<String,Long> currentBytesUsedPerMP; 309 310 // The list of average collection durations per garbage collector. 311 private final Map<String,Long> averageCollectionDurationPerGC; 312 313 // The list of recent collection durations per garbage collector. 314 private final Map<String,Long> recentCollectionDurationPerGC; 315 316 // The list of total collection counts per garbage collector. 317 private final Map<String,Long> totalCollectionCountPerGC; 318 319 // The list of total collection durations per garbage collector. 320 private final Map<String,Long> totalCollectionDurationPerGC; 321 322 323 324 /** 325 * Creates a new memory usage monitor entry from the provided entry. 326 * 327 * @param entry The entry to be parsed as a memory usage monitor entry. It 328 * must not be {@code null}. 329 */ 330 public MemoryUsageMonitorEntry(final Entry entry) 331 { 332 super(entry); 333 334 maxDetectedPauseTime = getLong(ATTR_LONGEST_PAUSE_TIME); 335 nonHeapMemoryUsed = getLong(ATTR_NON_HEAP_USED); 336 totalBytesHeldByConsumers = getLong(ATTR_TOTAL_CONSUMER_MEMORY); 337 percentOfCommittedTenuredMemory = 338 getLong(ATTR_TOTAL_CONSUMER_MEMORY_AS_PCT_OF_COMMITTED); 339 percentOfMaxTenuredMemory = 340 getLong(ATTR_TOTAL_CONSUMER_MEMORY_AS_PCT_OF_MAX); 341 342 maxReservableMemoryMB = getLong(ATTR_MAX_RESERVABLE_MEMORY_MB); 343 currentReservedMemoryMB = getLong(ATTR_CURRENT_RESERVED_MEMORY_MB); 344 usedReservedMemoryMB = getLong(ATTR_USED_MEMORY_MB); 345 freeReservedMemoryMB = getLong(ATTR_FREE_MEMORY_MB); 346 reservedMemoryPercentFull = getLong(ATTR_RESERVED_MEMORY_PERCENT_FULL); 347 348 349 final TreeMap<Long,Long> pauses = new TreeMap<Long,Long>(); 350 351 final TreeSet<String> mpNames = new TreeSet<String>(); 352 final TreeSet<String> gcNames = new TreeSet<String>(); 353 354 final TreeMap<String,Long> averageDurations = new TreeMap<String,Long>(); 355 final TreeMap<String,Long> currentBytesUsed = new TreeMap<String,Long>(); 356 final TreeMap<String,Long> lastBytesUsed = new TreeMap<String,Long>(); 357 final TreeMap<String,Long> recentDurations = new TreeMap<String,Long>(); 358 final TreeMap<String,Long> totalCounts = new TreeMap<String,Long>(); 359 final TreeMap<String,Long> totalDurations = new TreeMap<String,Long>(); 360 361 for (final Attribute a : entry.getAttributes()) 362 { 363 final String name = a.getName(); 364 final String lowerName = toLowerCase(name); 365 366 if (lowerName.startsWith(ATTR_PREFIX_DETECTED_PAUSE)) 367 { 368 final Long l = getLong(name); 369 370 final String timeStr = 371 lowerName.substring(ATTR_PREFIX_DETECTED_PAUSE.length()); 372 if (timeStr.endsWith("ms")) 373 { 374 try 375 { 376 final long millis = 377 Long.parseLong(timeStr.substring(0, timeStr.length()-2)); 378 pauses.put(millis, l); 379 } 380 catch (Exception e) 381 { 382 debugException(e); 383 } 384 } 385 else if (timeStr.endsWith("s")) 386 { 387 try 388 { 389 final long millis = 1000 * 390 Long.parseLong(timeStr.substring(0, timeStr.length()-1)); 391 pauses.put(millis, l); 392 } 393 catch (Exception e) 394 { 395 debugException(e); 396 } 397 } 398 } 399 400 int pos = lowerName.indexOf(ATTR_SUFFIX_AVERAGE_COLLECTION_DURATION); 401 if (pos > 0) 402 { 403 final String gcName = name.substring(0, pos); 404 gcNames.add(gcName); 405 406 final Long l = getLong(name); 407 if (l != null) 408 { 409 averageDurations.put(toLowerCase(gcName), l); 410 } 411 412 continue; 413 } 414 415 pos = lowerName.indexOf(ATTR_SUFFIX_BYTES_USED_AFTER_LAST_COLLECTION); 416 if (pos > 0) 417 { 418 final String mpName = name.substring(0, pos); 419 mpNames.add(mpName); 420 421 final Long l = getLong(name); 422 if (l != null) 423 { 424 lastBytesUsed.put(toLowerCase(mpName), l); 425 } 426 427 continue; 428 } 429 430 pos = lowerName.indexOf(ATTR_SUFFIX_CURRENT_BYTES_USED); 431 if (pos > 0) 432 { 433 final String mpName = name.substring(0, pos); 434 mpNames.add(mpName); 435 436 final Long l = getLong(name); 437 if (l != null) 438 { 439 currentBytesUsed.put(toLowerCase(mpName), l); 440 } 441 442 continue; 443 } 444 445 pos = lowerName.indexOf(ATTR_SUFFIX_RECENT_COLLECTION_DURATION); 446 if (pos > 0) 447 { 448 final String gcName = name.substring(0, pos); 449 gcNames.add(gcName); 450 451 final Long l = getLong(name); 452 if (l != null) 453 { 454 recentDurations.put(toLowerCase(gcName), l); 455 } 456 457 continue; 458 } 459 460 pos = lowerName.indexOf(ATTR_SUFFIX_TOTAL_COLLECTION_COUNT); 461 if ((pos > 0) && (! lowerName.startsWith("mem-pool-"))) 462 { 463 final String gcName = name.substring(0, pos); 464 gcNames.add(gcName); 465 466 final Long l = getLong(name); 467 if (l != null) 468 { 469 totalCounts.put(toLowerCase(gcName), l); 470 } 471 472 continue; 473 } 474 475 pos = lowerName.indexOf(ATTR_SUFFIX_TOTAL_COLLECTION_DURATION); 476 if (pos > 0) 477 { 478 final String gcName = name.substring(0, pos); 479 gcNames.add(gcName); 480 481 final Long l = getLong(name); 482 if (l != null) 483 { 484 totalDurations.put(toLowerCase(gcName), l); 485 } 486 487 continue; 488 } 489 } 490 491 492 garbageCollectors = 493 Collections.unmodifiableList(new ArrayList<String>(gcNames)); 494 495 memoryPools = Collections.unmodifiableList(new ArrayList<String>(mpNames)); 496 497 totalCollectionCountPerGC = Collections.unmodifiableMap(totalCounts); 498 499 totalCollectionDurationPerGC = Collections.unmodifiableMap(totalDurations); 500 501 averageCollectionDurationPerGC = 502 Collections.unmodifiableMap(averageDurations); 503 504 recentCollectionDurationPerGC = 505 Collections.unmodifiableMap(recentDurations); 506 507 bytesUsedAfterLastCollectionPerMP = 508 Collections.unmodifiableMap(lastBytesUsed); 509 510 currentBytesUsedPerMP = Collections.unmodifiableMap(currentBytesUsed); 511 512 detectedPauses = Collections.unmodifiableMap(pauses); 513 } 514 515 516 517 /** 518 * Retrieves the maximum amount of memory (in megabytes) that may be allocated 519 * and used by the JVM. 520 * 521 * @return The maximum amount of memory (in megabytes) that may be allocated 522 * and used by the JVM, or {@code null} if this was not included in 523 * the monitor entry. 524 */ 525 public Long getMaxReservableMemoryMB() 526 { 527 return maxReservableMemoryMB; 528 } 529 530 531 532 /** 533 * Retrieves the amount of memory (in megabytes) that is currently allocated 534 * for use by the JVM. 535 * 536 * @return The amount of memory (in megabytes) that is currently allocated 537 * for use by the JVM, or {@code null} if this was not included in 538 * the monitor entry. 539 */ 540 public Long getCurrentReservedMemoryMB() 541 { 542 return currentReservedMemoryMB; 543 } 544 545 546 547 /** 548 * Retrieves the amount of memory (in megabytes) allocated for use by the JVM 549 * that is currently in use for holding Java objects. 550 * 551 * @return The amount of memory (in megabytes) allocated for use by the JVM 552 * that is currently in use for holding Java objects, or {@code null} 553 * if this was not included in the monitor entry. 554 */ 555 public Long getUsedReservedMemoryMB() 556 { 557 return usedReservedMemoryMB; 558 } 559 560 561 562 /** 563 * Retrieves the amount of memory (in megabytes) allocated for use by the JVM 564 * that is not currently in use for holding Java objects. 565 * 566 * @return The amount of memory (in megabytes) allocated for use by the JVM 567 * that is not currently in use for holding Java objects, or 568 * {@code null} if this was not included in the monitor entry. 569 */ 570 public Long getFreeReservedMemoryMB() 571 { 572 return freeReservedMemoryMB; 573 } 574 575 576 577 /** 578 * Retrieves the percent of the currently-reserved memory that is actually in 579 * use by the JVM for storing Java objects. 580 * 581 * @return The percent of the currently-reserved memory that is actually in 582 * use by the JVM for storing Java objects. 583 */ 584 public Long getReservedMemoryPercentFull() 585 { 586 return reservedMemoryPercentFull; 587 } 588 589 590 591 /** 592 * Retrieves the names of the garbage collectors for which information is 593 * available. 594 * 595 * @return The names of the garbage collectors for which information is 596 * available. 597 */ 598 public List<String> getGarbageCollectorNames() 599 { 600 return garbageCollectors; 601 } 602 603 604 605 /** 606 * Retrieves the names of the memory pools for which information is available. 607 * 608 * @return The names of the memory pools for which information is available. 609 */ 610 public List<String> getMemoryPoolNames() 611 { 612 return memoryPools; 613 } 614 615 616 617 /** 618 * Retrieves a map containing the total number of garbage collections 619 * performed per collector. 620 * 621 * @return A map containing the total number of garbage collections performed 622 * per collector. 623 */ 624 public Map<String,Long> getTotalCollectionCounts() 625 { 626 return totalCollectionCountPerGC; 627 } 628 629 630 631 /** 632 * Retrieves the total number of garbage collections performed by the 633 * specified collector. 634 * 635 * @param collectorName The name of the garbage collector for which to 636 * retrieve the information. 637 * 638 * @return The total number of garbage collections performed by the specified 639 * collector, or {@code null} if that information is not available. 640 */ 641 public Long getTotalCollectionCount(final String collectorName) 642 { 643 return totalCollectionCountPerGC.get(toLowerCase(collectorName)); 644 } 645 646 647 648 /** 649 * Retrieves a map containing the total length of time (in milliseconds) spent 650 * performing garbage collection per collector. 651 * 652 * @return A map containing the total length of time (in milliseconds) spent 653 * performing garbage collection per collector. 654 */ 655 public Map<String,Long> getTotalCollectionDurations() 656 { 657 return totalCollectionDurationPerGC; 658 } 659 660 661 662 /** 663 * Retrieves the total length of time (in milliseconds) spent performing 664 * garbage collection for the specified collector. 665 * 666 * @param collectorName The name of the garbage collector for which to 667 * retrieve the information. 668 * 669 * @return The total length of time (in milliseconds) spent performing 670 * garbage collection for the specified collector, or {@code null} if 671 * that information is not available. 672 */ 673 public Long getTotalCollectionDuration(final String collectorName) 674 { 675 return totalCollectionDurationPerGC.get(toLowerCase(collectorName)); 676 } 677 678 679 680 /** 681 * Retrieves a map containing the average garbage collection duration (in 682 * milliseconds) per garbage collector. 683 * 684 * @return A map containing the average garbage collection duration (in 685 * milliseconds) per garbage collector. 686 */ 687 public Map<String,Long> getAverageCollectionDurations() 688 { 689 return averageCollectionDurationPerGC; 690 } 691 692 693 694 /** 695 * Retrieves the average garbage collection duration (in milliseconds) for the 696 * specified collector. 697 * 698 * @param collectorName The name of the garbage collector for which to 699 * retrieve the information. 700 * 701 * @return The average garbage collection duration (in milliseconds) for the 702 * specified collector, or {@code null} if that information is not 703 * available. 704 */ 705 public Long getAverageCollectionDuration(final String collectorName) 706 { 707 return averageCollectionDurationPerGC.get(toLowerCase(collectorName)); 708 } 709 710 711 712 /** 713 * Retrieves a map containing the most recent garbage collection duration (in 714 * milliseconds) per garbage collector. 715 * 716 * @return A map containing the duration of the most recent garbage 717 * collection duration (in milliseconds) per garbage collector. 718 */ 719 public Map<String,Long> getRecentCollectionDurations() 720 { 721 return recentCollectionDurationPerGC; 722 } 723 724 725 726 /** 727 * Retrieves the duration (in milliseconds) of the most recent garbage 728 * collection for the specified collector. 729 * 730 * @param collectorName The name of the garbage collector for which to 731 * retrieve the information. 732 * 733 * @return The duration (in milliseconds) of the most recent garbage 734 * collection for the specified collector, or {@code null} if that 735 * information is not available. 736 */ 737 public Long getRecentCollectionDuration(final String collectorName) 738 { 739 return recentCollectionDurationPerGC.get(toLowerCase(collectorName)); 740 } 741 742 743 744 /** 745 * Retrieves a map containing the current number of bytes used per memory 746 * pool. 747 * 748 * @return A map containing the current number of bytes used per memory pool. 749 */ 750 public Map<String,Long> getCurrentBytesUsed() 751 { 752 return currentBytesUsedPerMP; 753 } 754 755 756 757 /** 758 * Retrieves the current number of bytes used for the specified memory pool. 759 * 760 * @param poolName The name of the memory pool for which to retrieve the 761 * information. 762 * 763 * @return The current number of bytes used for the specified memory pool, or 764 * {@code null} if that information is not available. 765 */ 766 public Long getCurrentBytesUsed(final String poolName) 767 { 768 return currentBytesUsedPerMP.get(toLowerCase(poolName)); 769 } 770 771 772 773 /** 774 * Retrieves a map containing the number of bytes used after the last garbage 775 * collection per memory pool. 776 * 777 * @return A map containing the number of bytes used after the last garbage 778 * collection per memory pool. 779 */ 780 public Map<String,Long> getBytesUsedAfterLastCollection() 781 { 782 return bytesUsedAfterLastCollectionPerMP; 783 } 784 785 786 787 /** 788 * Retrieves the number of bytes used after the last garbage collection for 789 * the specified memory pool. 790 * 791 * @param poolName The name of the memory pool for which to retrieve the 792 * information. 793 * 794 * @return The number of bytes used after the last garbage collection for the 795 * specified memory pool, or {@code null} if that information is not 796 * available. 797 */ 798 public Long getBytesUsedAfterLastCollection(final String poolName) 799 { 800 return bytesUsedAfterLastCollectionPerMP.get(toLowerCase(poolName)); 801 } 802 803 804 805 /** 806 * Retrieves the amount of non-heap memory consumed by the JVM. 807 * 808 * @return The amount of non-heap memory consumed by the JVM, or {@code null} 809 * if that information is not available. 810 */ 811 public Long getNonHeapMemoryBytesUsed() 812 { 813 return nonHeapMemoryUsed; 814 } 815 816 817 818 /** 819 * Retrieves the total amount of memory in bytes held by memory consumers. 820 * 821 * @return The total amount of memory in bytes held by memory consumers, or 822 * {@code null} if that information is not available. 823 */ 824 public Long getTotalBytesUsedByMemoryConsumers() 825 { 826 return totalBytesHeldByConsumers; 827 } 828 829 830 831 /** 832 * Retrieves the percentage of the maximum allowed amount of tenured memory 833 * that is used by memory consumers (assuming that all memory used by memory 834 * consumers is contained in the tenured generation). 835 * 836 * @return The percentage of the maximum allowed amount of tenured memory 837 * that is used by memory consumers, or {@code null} if that 838 * information is not available. 839 */ 840 public Long getPercentageOfMaximumTenuredMemoryUsedByMemoryConsumers() 841 { 842 return percentOfMaxTenuredMemory; 843 } 844 845 846 847 /** 848 * Retrieves the percentage of the committed amount of tenured memory that is 849 * used by memory consumers (assuming that all memory used by memory consumers 850 * is contained in the tenured generation). 851 * 852 * @return The percentage of the committed amount of tenured memory that is 853 * used by memory consumers, or {@code null} if that information is 854 * not available. 855 */ 856 public Long getPercentageOfCommittedTenuredMemoryUsedByMemoryConsumers() 857 { 858 return percentOfCommittedTenuredMemory; 859 } 860 861 862 863 /** 864 * Retrieves the number of pauses of various durations detected by the server. 865 * The value returned will contain a map between the minimum duration in 866 * milliseconds for the associated bucket and the number of pauses detected of 867 * at least that duration. 868 * 869 * @return The number of pauses of various durations detected by the server. 870 */ 871 public Map<Long,Long> getDetectedPauseCounts() 872 { 873 return detectedPauses; 874 } 875 876 877 878 /** 879 * Retrieves the duration of the longest pause detected by the server. 880 * 881 * @return The duration of the longest pause detected by the server, or 882 * {@code null} if that information is not available. 883 */ 884 public Long getMaxDetectedPauseTimeMillis() 885 { 886 return maxDetectedPauseTime; 887 } 888 889 890 891 /** 892 * {@inheritDoc} 893 */ 894 @Override() 895 public String getMonitorDisplayName() 896 { 897 return INFO_MEMORY_USAGE_MONITOR_DISPNAME.get(); 898 } 899 900 901 902 /** 903 * {@inheritDoc} 904 */ 905 @Override() 906 public String getMonitorDescription() 907 { 908 return INFO_MEMORY_USAGE_MONITOR_DESC.get(); 909 } 910 911 912 913 /** 914 * {@inheritDoc} 915 */ 916 @Override() 917 public Map<String,MonitorAttribute> getMonitorAttributes() 918 { 919 final LinkedHashMap<String,MonitorAttribute> attrs = 920 new LinkedHashMap<String,MonitorAttribute>(); 921 922 if (maxReservableMemoryMB != null) 923 { 924 addMonitorAttribute(attrs, 925 ATTR_MAX_RESERVABLE_MEMORY_MB, 926 INFO_MEMORY_USAGE_DISPNAME_MAX_MEM.get(), 927 INFO_MEMORY_USAGE_DESC_MAX_MEM.get(), 928 maxReservableMemoryMB); 929 } 930 931 if (currentReservedMemoryMB != null) 932 { 933 addMonitorAttribute(attrs, 934 ATTR_CURRENT_RESERVED_MEMORY_MB, 935 INFO_MEMORY_USAGE_DISPNAME_CURRENT_MEM.get(), 936 INFO_MEMORY_USAGE_DESC_CURRENT_MEM.get(), 937 currentReservedMemoryMB); 938 } 939 940 if (usedReservedMemoryMB != null) 941 { 942 addMonitorAttribute(attrs, 943 ATTR_USED_MEMORY_MB, 944 INFO_MEMORY_USAGE_DISPNAME_USED_MEM.get(), 945 INFO_MEMORY_USAGE_DESC_USED_MEM.get(), 946 usedReservedMemoryMB); 947 } 948 949 if (freeReservedMemoryMB != null) 950 { 951 addMonitorAttribute(attrs, 952 ATTR_FREE_MEMORY_MB, 953 INFO_MEMORY_USAGE_DISPNAME_FREE_MEM.get(), 954 INFO_MEMORY_USAGE_DESC_FREE_MEM.get(), 955 freeReservedMemoryMB); 956 } 957 958 if (reservedMemoryPercentFull != null) 959 { 960 addMonitorAttribute(attrs, 961 ATTR_RESERVED_MEMORY_PERCENT_FULL, 962 INFO_MEMORY_USAGE_DISPNAME_RESERVED_PCT.get(), 963 INFO_MEMORY_USAGE_DESC_RESERVED_PCT.get(), 964 reservedMemoryPercentFull); 965 } 966 967 if (! garbageCollectors.isEmpty()) 968 { 969 addMonitorAttribute(attrs, 970 "gcNames", 971 INFO_MEMORY_USAGE_DISPNAME_GC_NAMES.get(), 972 INFO_MEMORY_USAGE_DESC_GC_NAMES.get(), 973 garbageCollectors); 974 } 975 976 if (! totalCollectionCountPerGC.isEmpty()) 977 { 978 for (final String name : totalCollectionCountPerGC.keySet()) 979 { 980 addMonitorAttribute(attrs, 981 "totalCollectionCount-" + name, 982 INFO_MEMORY_USAGE_DISPNAME_TOTAL_COLLECTION_COUNT.get(name), 983 INFO_MEMORY_USAGE_DESC_TOTAL_COLLECTION_COUNT.get(name), 984 totalCollectionCountPerGC.get(name)); 985 } 986 } 987 988 if (! totalCollectionDurationPerGC.isEmpty()) 989 { 990 for (final String name : totalCollectionDurationPerGC.keySet()) 991 { 992 addMonitorAttribute(attrs, 993 "totalCollectionDuration-" + name, 994 INFO_MEMORY_USAGE_DISPNAME_TOTAL_COLLECTION_DURATION.get(name), 995 INFO_MEMORY_USAGE_DESC_TOTAL_COLLECTION_DURATION.get(name), 996 totalCollectionDurationPerGC.get(name)); 997 } 998 } 999 1000 if (! averageCollectionDurationPerGC.isEmpty()) 1001 { 1002 for (final String name : averageCollectionDurationPerGC.keySet()) 1003 { 1004 addMonitorAttribute(attrs, 1005 "averageCollectionDuration-" + name, 1006 INFO_MEMORY_USAGE_DISPNAME_AVERAGE_COLLECTION_DURATION.get(name), 1007 INFO_MEMORY_USAGE_DESC_AVERAGE_COLLECTION_DURATION.get(name), 1008 averageCollectionDurationPerGC.get(name)); 1009 } 1010 } 1011 1012 if (! recentCollectionDurationPerGC.isEmpty()) 1013 { 1014 for (final String name : recentCollectionDurationPerGC.keySet()) 1015 { 1016 addMonitorAttribute(attrs, 1017 "recentCollectionDuration-" + name, 1018 INFO_MEMORY_USAGE_DISPNAME_RECENT_COLLECTION_DURATION.get(name), 1019 INFO_MEMORY_USAGE_DESC_RECENT_COLLECTION_DURATION.get(name), 1020 recentCollectionDurationPerGC.get(name)); 1021 } 1022 } 1023 1024 if (! memoryPools.isEmpty()) 1025 { 1026 addMonitorAttribute(attrs, 1027 "memoryPools", 1028 INFO_MEMORY_USAGE_DISPNAME_MEMORY_POOLS.get(), 1029 INFO_MEMORY_USAGE_DESC_MEMORY_POOLS.get(), 1030 memoryPools); 1031 } 1032 1033 if (! currentBytesUsedPerMP.isEmpty()) 1034 { 1035 for (final String name : currentBytesUsedPerMP.keySet()) 1036 { 1037 addMonitorAttribute(attrs, 1038 "currentBytesUsed-" + name, 1039 INFO_MEMORY_USAGE_DISPNAME_CURRENT_BYTES_USED.get(name), 1040 INFO_MEMORY_USAGE_DESC_CURRENT_BYTES_USED.get(name), 1041 currentBytesUsedPerMP.get(name)); 1042 } 1043 } 1044 1045 if (! bytesUsedAfterLastCollectionPerMP.isEmpty()) 1046 { 1047 for (final String name : bytesUsedAfterLastCollectionPerMP.keySet()) 1048 { 1049 addMonitorAttribute(attrs, 1050 "bytesUsedAfterLastCollection-" + name, 1051 INFO_MEMORY_USAGE_DISPNAME_BYTES_USED_AFTER_COLLECTION.get(name), 1052 INFO_MEMORY_USAGE_DESC_BYTES_USED_AFTER_COLLECTION.get(name), 1053 bytesUsedAfterLastCollectionPerMP.get(name)); 1054 } 1055 } 1056 1057 if (nonHeapMemoryUsed != null) 1058 { 1059 addMonitorAttribute(attrs, 1060 ATTR_NON_HEAP_USED, 1061 INFO_MEMORY_USAGE_DISPNAME_NON_HEAP_MEMORY.get(), 1062 INFO_MEMORY_USAGE_DESC_NON_HEAP_MEMORY.get(), 1063 nonHeapMemoryUsed); 1064 } 1065 1066 if (totalBytesHeldByConsumers != null) 1067 { 1068 addMonitorAttribute(attrs, 1069 ATTR_TOTAL_CONSUMER_MEMORY, 1070 INFO_MEMORY_USAGE_DISPNAME_TOTAL_CONSUMER_MEMORY.get(), 1071 INFO_MEMORY_USAGE_DESC_TOTAL_CONSUMER_MEMORY.get(), 1072 totalBytesHeldByConsumers); 1073 } 1074 1075 if (percentOfMaxTenuredMemory != null) 1076 { 1077 addMonitorAttribute(attrs, 1078 ATTR_TOTAL_CONSUMER_MEMORY_AS_PCT_OF_MAX, 1079 INFO_MEMORY_USAGE_DISPNAME_CONSUMERS_AS_PCT_OF_MAX.get(), 1080 INFO_MEMORY_USAGE_DESC_CONSUMERS_AS_PCT_OF_MAX.get(), 1081 percentOfMaxTenuredMemory); 1082 } 1083 1084 if (percentOfCommittedTenuredMemory != null) 1085 { 1086 addMonitorAttribute(attrs, 1087 ATTR_TOTAL_CONSUMER_MEMORY_AS_PCT_OF_COMMITTED, 1088 INFO_MEMORY_USAGE_DISPNAME_CONSUMERS_AS_PCT_OF_COMMITTED.get(), 1089 INFO_MEMORY_USAGE_DESC_CONSUMERS_AS_PCT_OF_COMMITTED.get(), 1090 percentOfCommittedTenuredMemory); 1091 } 1092 1093 if (! detectedPauses.isEmpty()) 1094 { 1095 final ArrayList<String> values = 1096 new ArrayList<String>(detectedPauses.size()); 1097 for (final Map.Entry<Long,Long> e : detectedPauses.entrySet()) 1098 { 1099 values.add(e.getKey() + "ms=" + e.getValue()); 1100 } 1101 1102 addMonitorAttribute(attrs, 1103 PROPERTY_DETECTED_PAUSE_COUNTS, 1104 INFO_MEMORY_USAGE_DISPNAME_DETECTED_PAUSES.get(), 1105 INFO_MEMORY_USAGE_DESC_DETECTED_PAUSES.get(), 1106 values); 1107 } 1108 1109 if (maxDetectedPauseTime != null) 1110 { 1111 addMonitorAttribute(attrs, 1112 ATTR_LONGEST_PAUSE_TIME, 1113 INFO_MEMORY_USAGE_DISPNAME_MAX_PAUSE_TIME.get(), 1114 INFO_MEMORY_USAGE_DESC_MAX_PAUSE_TIME.get(), 1115 maxDetectedPauseTime); 1116 } 1117 1118 return Collections.unmodifiableMap(attrs); 1119 } 1120 }