001/* 002 * Copyright 2008-2018 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2015-2018 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.NotMutable; 036import com.unboundid.util.ThreadSafety; 037import com.unboundid.util.ThreadSafetyLevel; 038 039import static com.unboundid.ldap.sdk.unboundidds.monitors.MonitorMessages.*; 040import static com.unboundid.util.Debug.*; 041import static com.unboundid.util.StaticUtils.*; 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 Alcatel-Lucent 8661 055 * server products. These classes provide support for proprietary 056 * functionality or for external specifications that are not considered stable 057 * or mature enough to be guaranteed to work in an interoperable way with 058 * 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<Long,Long>(); 356 357 final TreeSet<String> mpNames = new TreeSet<String>(); 358 final TreeSet<String> gcNames = new TreeSet<String>(); 359 360 final TreeMap<String,Long> averageDurations = new TreeMap<String,Long>(); 361 final TreeMap<String,Long> currentBytesUsed = new TreeMap<String,Long>(); 362 final TreeMap<String,Long> lastBytesUsed = new TreeMap<String,Long>(); 363 final TreeMap<String,Long> recentDurations = new TreeMap<String,Long>(); 364 final TreeMap<String,Long> totalCounts = new TreeMap<String,Long>(); 365 final TreeMap<String,Long> totalDurations = new TreeMap<String,Long>(); 366 367 for (final Attribute a : entry.getAttributes()) 368 { 369 final String name = a.getName(); 370 final String lowerName = 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 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 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(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(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(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(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(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(toLowerCase(gcName), l); 491 } 492 493 continue; 494 } 495 } 496 497 498 garbageCollectors = 499 Collections.unmodifiableList(new ArrayList<String>(gcNames)); 500 501 memoryPools = Collections.unmodifiableList(new ArrayList<String>(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(toLowerCase(collectorName)); 650 } 651 652 653 654 /** 655 * Retrieves a map containing the total length of time (in milliseconds) spent 656 * performing garbage collection per collector. 657 * 658 * @return A map containing the total length of time (in milliseconds) spent 659 * performing garbage collection per collector. 660 */ 661 public Map<String,Long> getTotalCollectionDurations() 662 { 663 return totalCollectionDurationPerGC; 664 } 665 666 667 668 /** 669 * Retrieves the total length of time (in milliseconds) spent performing 670 * garbage collection for the specified collector. 671 * 672 * @param collectorName The name of the garbage collector for which to 673 * retrieve the information. 674 * 675 * @return The total length of time (in milliseconds) spent performing 676 * garbage collection for the specified collector, or {@code null} if 677 * that information is not available. 678 */ 679 public Long getTotalCollectionDuration(final String collectorName) 680 { 681 return totalCollectionDurationPerGC.get(toLowerCase(collectorName)); 682 } 683 684 685 686 /** 687 * Retrieves a map containing the average garbage collection duration (in 688 * milliseconds) per garbage collector. 689 * 690 * @return A map containing the average garbage collection duration (in 691 * milliseconds) per garbage collector. 692 */ 693 public Map<String,Long> getAverageCollectionDurations() 694 { 695 return averageCollectionDurationPerGC; 696 } 697 698 699 700 /** 701 * Retrieves the average garbage collection duration (in milliseconds) for the 702 * specified collector. 703 * 704 * @param collectorName The name of the garbage collector for which to 705 * retrieve the information. 706 * 707 * @return The average garbage collection duration (in milliseconds) for the 708 * specified collector, or {@code null} if that information is not 709 * available. 710 */ 711 public Long getAverageCollectionDuration(final String collectorName) 712 { 713 return averageCollectionDurationPerGC.get(toLowerCase(collectorName)); 714 } 715 716 717 718 /** 719 * Retrieves a map containing the most recent garbage collection duration (in 720 * milliseconds) per garbage collector. 721 * 722 * @return A map containing the duration of the most recent garbage 723 * collection duration (in milliseconds) per garbage collector. 724 */ 725 public Map<String,Long> getRecentCollectionDurations() 726 { 727 return recentCollectionDurationPerGC; 728 } 729 730 731 732 /** 733 * Retrieves the duration (in milliseconds) of the most recent garbage 734 * collection for the specified collector. 735 * 736 * @param collectorName The name of the garbage collector for which to 737 * retrieve the information. 738 * 739 * @return The duration (in milliseconds) of the most recent garbage 740 * collection for the specified collector, or {@code null} if that 741 * information is not available. 742 */ 743 public Long getRecentCollectionDuration(final String collectorName) 744 { 745 return recentCollectionDurationPerGC.get(toLowerCase(collectorName)); 746 } 747 748 749 750 /** 751 * Retrieves a map containing the current number of bytes used per memory 752 * pool. 753 * 754 * @return A map containing the current number of bytes used per memory pool. 755 */ 756 public Map<String,Long> getCurrentBytesUsed() 757 { 758 return currentBytesUsedPerMP; 759 } 760 761 762 763 /** 764 * Retrieves the current number of bytes used for the specified memory pool. 765 * 766 * @param poolName The name of the memory pool for which to retrieve the 767 * information. 768 * 769 * @return The current number of bytes used for the specified memory pool, or 770 * {@code null} if that information is not available. 771 */ 772 public Long getCurrentBytesUsed(final String poolName) 773 { 774 return currentBytesUsedPerMP.get(toLowerCase(poolName)); 775 } 776 777 778 779 /** 780 * Retrieves a map containing the number of bytes used after the last garbage 781 * collection per memory pool. 782 * 783 * @return A map containing the number of bytes used after the last garbage 784 * collection per memory pool. 785 */ 786 public Map<String,Long> getBytesUsedAfterLastCollection() 787 { 788 return bytesUsedAfterLastCollectionPerMP; 789 } 790 791 792 793 /** 794 * Retrieves the number of bytes used after the last garbage collection for 795 * the specified memory pool. 796 * 797 * @param poolName The name of the memory pool for which to retrieve the 798 * information. 799 * 800 * @return The number of bytes used after the last garbage collection for the 801 * specified memory pool, or {@code null} if that information is not 802 * available. 803 */ 804 public Long getBytesUsedAfterLastCollection(final String poolName) 805 { 806 return bytesUsedAfterLastCollectionPerMP.get(toLowerCase(poolName)); 807 } 808 809 810 811 /** 812 * Retrieves the amount of non-heap memory consumed by the JVM. 813 * 814 * @return The amount of non-heap memory consumed by the JVM, or {@code null} 815 * if that information is not available. 816 */ 817 public Long getNonHeapMemoryBytesUsed() 818 { 819 return nonHeapMemoryUsed; 820 } 821 822 823 824 /** 825 * Retrieves the total amount of memory in bytes held by memory consumers. 826 * 827 * @return The total amount of memory in bytes held by memory consumers, or 828 * {@code null} if that information is not available. 829 */ 830 public Long getTotalBytesUsedByMemoryConsumers() 831 { 832 return totalBytesHeldByConsumers; 833 } 834 835 836 837 /** 838 * Retrieves the percentage of the maximum allowed amount of tenured memory 839 * that is used by memory consumers (assuming that all memory used by memory 840 * consumers is contained in the tenured generation). 841 * 842 * @return The percentage of the maximum allowed amount of tenured memory 843 * that is used by memory consumers, or {@code null} if that 844 * information is not available. 845 */ 846 public Long getPercentageOfMaximumTenuredMemoryUsedByMemoryConsumers() 847 { 848 return percentOfMaxTenuredMemory; 849 } 850 851 852 853 /** 854 * Retrieves the percentage of the committed amount of tenured memory that is 855 * used by memory consumers (assuming that all memory used by memory consumers 856 * is contained in the tenured generation). 857 * 858 * @return The percentage of the committed amount of tenured memory that is 859 * used by memory consumers, or {@code null} if that information is 860 * not available. 861 */ 862 public Long getPercentageOfCommittedTenuredMemoryUsedByMemoryConsumers() 863 { 864 return percentOfCommittedTenuredMemory; 865 } 866 867 868 869 /** 870 * Retrieves the number of pauses of various durations detected by the server. 871 * The value returned will contain a map between the minimum duration in 872 * milliseconds for the associated bucket and the number of pauses detected of 873 * at least that duration. 874 * 875 * @return The number of pauses of various durations detected by the server. 876 */ 877 public Map<Long,Long> getDetectedPauseCounts() 878 { 879 return detectedPauses; 880 } 881 882 883 884 /** 885 * Retrieves the duration of the longest pause detected by the server. 886 * 887 * @return The duration of the longest pause detected by the server, or 888 * {@code null} if that information is not available. 889 */ 890 public Long getMaxDetectedPauseTimeMillis() 891 { 892 return maxDetectedPauseTime; 893 } 894 895 896 897 /** 898 * {@inheritDoc} 899 */ 900 @Override() 901 public String getMonitorDisplayName() 902 { 903 return INFO_MEMORY_USAGE_MONITOR_DISPNAME.get(); 904 } 905 906 907 908 /** 909 * {@inheritDoc} 910 */ 911 @Override() 912 public String getMonitorDescription() 913 { 914 return INFO_MEMORY_USAGE_MONITOR_DESC.get(); 915 } 916 917 918 919 /** 920 * {@inheritDoc} 921 */ 922 @Override() 923 public Map<String,MonitorAttribute> getMonitorAttributes() 924 { 925 final LinkedHashMap<String,MonitorAttribute> attrs = 926 new LinkedHashMap<String,MonitorAttribute>(); 927 928 if (maxReservableMemoryMB != null) 929 { 930 addMonitorAttribute(attrs, 931 ATTR_MAX_RESERVABLE_MEMORY_MB, 932 INFO_MEMORY_USAGE_DISPNAME_MAX_MEM.get(), 933 INFO_MEMORY_USAGE_DESC_MAX_MEM.get(), 934 maxReservableMemoryMB); 935 } 936 937 if (currentReservedMemoryMB != null) 938 { 939 addMonitorAttribute(attrs, 940 ATTR_CURRENT_RESERVED_MEMORY_MB, 941 INFO_MEMORY_USAGE_DISPNAME_CURRENT_MEM.get(), 942 INFO_MEMORY_USAGE_DESC_CURRENT_MEM.get(), 943 currentReservedMemoryMB); 944 } 945 946 if (usedReservedMemoryMB != null) 947 { 948 addMonitorAttribute(attrs, 949 ATTR_USED_MEMORY_MB, 950 INFO_MEMORY_USAGE_DISPNAME_USED_MEM.get(), 951 INFO_MEMORY_USAGE_DESC_USED_MEM.get(), 952 usedReservedMemoryMB); 953 } 954 955 if (freeReservedMemoryMB != null) 956 { 957 addMonitorAttribute(attrs, 958 ATTR_FREE_MEMORY_MB, 959 INFO_MEMORY_USAGE_DISPNAME_FREE_MEM.get(), 960 INFO_MEMORY_USAGE_DESC_FREE_MEM.get(), 961 freeReservedMemoryMB); 962 } 963 964 if (reservedMemoryPercentFull != null) 965 { 966 addMonitorAttribute(attrs, 967 ATTR_RESERVED_MEMORY_PERCENT_FULL, 968 INFO_MEMORY_USAGE_DISPNAME_RESERVED_PCT.get(), 969 INFO_MEMORY_USAGE_DESC_RESERVED_PCT.get(), 970 reservedMemoryPercentFull); 971 } 972 973 if (! garbageCollectors.isEmpty()) 974 { 975 addMonitorAttribute(attrs, 976 "gcNames", 977 INFO_MEMORY_USAGE_DISPNAME_GC_NAMES.get(), 978 INFO_MEMORY_USAGE_DESC_GC_NAMES.get(), 979 garbageCollectors); 980 } 981 982 if (! totalCollectionCountPerGC.isEmpty()) 983 { 984 for (final String name : totalCollectionCountPerGC.keySet()) 985 { 986 addMonitorAttribute(attrs, 987 "totalCollectionCount-" + name, 988 INFO_MEMORY_USAGE_DISPNAME_TOTAL_COLLECTION_COUNT.get(name), 989 INFO_MEMORY_USAGE_DESC_TOTAL_COLLECTION_COUNT.get(name), 990 totalCollectionCountPerGC.get(name)); 991 } 992 } 993 994 if (! totalCollectionDurationPerGC.isEmpty()) 995 { 996 for (final String name : totalCollectionDurationPerGC.keySet()) 997 { 998 addMonitorAttribute(attrs, 999 "totalCollectionDuration-" + name, 1000 INFO_MEMORY_USAGE_DISPNAME_TOTAL_COLLECTION_DURATION.get(name), 1001 INFO_MEMORY_USAGE_DESC_TOTAL_COLLECTION_DURATION.get(name), 1002 totalCollectionDurationPerGC.get(name)); 1003 } 1004 } 1005 1006 if (! averageCollectionDurationPerGC.isEmpty()) 1007 { 1008 for (final String name : averageCollectionDurationPerGC.keySet()) 1009 { 1010 addMonitorAttribute(attrs, 1011 "averageCollectionDuration-" + name, 1012 INFO_MEMORY_USAGE_DISPNAME_AVERAGE_COLLECTION_DURATION.get(name), 1013 INFO_MEMORY_USAGE_DESC_AVERAGE_COLLECTION_DURATION.get(name), 1014 averageCollectionDurationPerGC.get(name)); 1015 } 1016 } 1017 1018 if (! recentCollectionDurationPerGC.isEmpty()) 1019 { 1020 for (final String name : recentCollectionDurationPerGC.keySet()) 1021 { 1022 addMonitorAttribute(attrs, 1023 "recentCollectionDuration-" + name, 1024 INFO_MEMORY_USAGE_DISPNAME_RECENT_COLLECTION_DURATION.get(name), 1025 INFO_MEMORY_USAGE_DESC_RECENT_COLLECTION_DURATION.get(name), 1026 recentCollectionDurationPerGC.get(name)); 1027 } 1028 } 1029 1030 if (! memoryPools.isEmpty()) 1031 { 1032 addMonitorAttribute(attrs, 1033 "memoryPools", 1034 INFO_MEMORY_USAGE_DISPNAME_MEMORY_POOLS.get(), 1035 INFO_MEMORY_USAGE_DESC_MEMORY_POOLS.get(), 1036 memoryPools); 1037 } 1038 1039 if (! currentBytesUsedPerMP.isEmpty()) 1040 { 1041 for (final String name : currentBytesUsedPerMP.keySet()) 1042 { 1043 addMonitorAttribute(attrs, 1044 "currentBytesUsed-" + name, 1045 INFO_MEMORY_USAGE_DISPNAME_CURRENT_BYTES_USED.get(name), 1046 INFO_MEMORY_USAGE_DESC_CURRENT_BYTES_USED.get(name), 1047 currentBytesUsedPerMP.get(name)); 1048 } 1049 } 1050 1051 if (! bytesUsedAfterLastCollectionPerMP.isEmpty()) 1052 { 1053 for (final String name : bytesUsedAfterLastCollectionPerMP.keySet()) 1054 { 1055 addMonitorAttribute(attrs, 1056 "bytesUsedAfterLastCollection-" + name, 1057 INFO_MEMORY_USAGE_DISPNAME_BYTES_USED_AFTER_COLLECTION.get(name), 1058 INFO_MEMORY_USAGE_DESC_BYTES_USED_AFTER_COLLECTION.get(name), 1059 bytesUsedAfterLastCollectionPerMP.get(name)); 1060 } 1061 } 1062 1063 if (nonHeapMemoryUsed != null) 1064 { 1065 addMonitorAttribute(attrs, 1066 ATTR_NON_HEAP_USED, 1067 INFO_MEMORY_USAGE_DISPNAME_NON_HEAP_MEMORY.get(), 1068 INFO_MEMORY_USAGE_DESC_NON_HEAP_MEMORY.get(), 1069 nonHeapMemoryUsed); 1070 } 1071 1072 if (totalBytesHeldByConsumers != null) 1073 { 1074 addMonitorAttribute(attrs, 1075 ATTR_TOTAL_CONSUMER_MEMORY, 1076 INFO_MEMORY_USAGE_DISPNAME_TOTAL_CONSUMER_MEMORY.get(), 1077 INFO_MEMORY_USAGE_DESC_TOTAL_CONSUMER_MEMORY.get(), 1078 totalBytesHeldByConsumers); 1079 } 1080 1081 if (percentOfMaxTenuredMemory != null) 1082 { 1083 addMonitorAttribute(attrs, 1084 ATTR_TOTAL_CONSUMER_MEMORY_AS_PCT_OF_MAX, 1085 INFO_MEMORY_USAGE_DISPNAME_CONSUMERS_AS_PCT_OF_MAX.get(), 1086 INFO_MEMORY_USAGE_DESC_CONSUMERS_AS_PCT_OF_MAX.get(), 1087 percentOfMaxTenuredMemory); 1088 } 1089 1090 if (percentOfCommittedTenuredMemory != null) 1091 { 1092 addMonitorAttribute(attrs, 1093 ATTR_TOTAL_CONSUMER_MEMORY_AS_PCT_OF_COMMITTED, 1094 INFO_MEMORY_USAGE_DISPNAME_CONSUMERS_AS_PCT_OF_COMMITTED.get(), 1095 INFO_MEMORY_USAGE_DESC_CONSUMERS_AS_PCT_OF_COMMITTED.get(), 1096 percentOfCommittedTenuredMemory); 1097 } 1098 1099 if (! detectedPauses.isEmpty()) 1100 { 1101 final ArrayList<String> values = 1102 new ArrayList<String>(detectedPauses.size()); 1103 for (final Map.Entry<Long,Long> e : detectedPauses.entrySet()) 1104 { 1105 values.add(e.getKey() + "ms=" + e.getValue()); 1106 } 1107 1108 addMonitorAttribute(attrs, 1109 PROPERTY_DETECTED_PAUSE_COUNTS, 1110 INFO_MEMORY_USAGE_DISPNAME_DETECTED_PAUSES.get(), 1111 INFO_MEMORY_USAGE_DESC_DETECTED_PAUSES.get(), 1112 values); 1113 } 1114 1115 if (maxDetectedPauseTime != null) 1116 { 1117 addMonitorAttribute(attrs, 1118 ATTR_LONGEST_PAUSE_TIME, 1119 INFO_MEMORY_USAGE_DISPNAME_MAX_PAUSE_TIME.get(), 1120 INFO_MEMORY_USAGE_DESC_MAX_PAUSE_TIME.get(), 1121 maxDetectedPauseTime); 1122 } 1123 1124 return Collections.unmodifiableMap(attrs); 1125 } 1126}