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