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