32
32
33
33
package org .opensearch .monitor .jvm ;
34
34
35
+ import org .opensearch .Version ;
35
36
import org .opensearch .common .io .stream .StreamInput ;
36
37
import org .opensearch .common .io .stream .StreamOutput ;
37
38
import org .opensearch .common .io .stream .Writeable ;
@@ -85,6 +86,11 @@ public static JvmStats jvmStats() {
85
86
try {
86
87
MemoryUsage usage = memoryPoolMXBean .getUsage ();
87
88
MemoryUsage peakUsage = memoryPoolMXBean .getPeakUsage ();
89
+ MemoryUsage collectionUsage = memoryPoolMXBean .getCollectionUsage ();
90
+ // For some pools, the collection usage may not be supported and the method returns null.
91
+ if (collectionUsage == null ) {
92
+ collectionUsage = new MemoryUsage (0 , 0 , 0 , 0 );
93
+ }
88
94
String name = GcNames .getByMemoryPoolName (memoryPoolMXBean .getName (), null );
89
95
if (name == null ) { // if we can't resolve it, its not interesting.... (Per Gen, Code Cache)
90
96
continue ;
@@ -93,8 +99,13 @@ public static JvmStats jvmStats() {
93
99
usage .getUsed () < 0 ? 0 : usage .getUsed (),
94
100
usage .getMax () < 0 ? 0 : usage .getMax (),
95
101
peakUsage .getUsed () < 0 ? 0 : peakUsage .getUsed (),
96
- peakUsage .getMax () < 0 ? 0 : peakUsage .getMax ()
97
- ));
102
+ peakUsage .getMax () < 0 ? 0 : peakUsage .getMax (),
103
+ new MemoryPoolGcStats (
104
+ collectionUsage .getUsed () < 0 ? 0 : collectionUsage .getUsed (),
105
+ collectionUsage .getMax () < 0 ? 0 : collectionUsage .getMax ()
106
+ )
107
+ ));
108
+
98
109
} catch (final Exception ignored ) {
99
110
100
111
}
@@ -223,6 +234,12 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
223
234
builder .humanReadableField (Fields .PEAK_USED_IN_BYTES , Fields .PEAK_USED , new ByteSizeValue (pool .peakUsed ));
224
235
builder .humanReadableField (Fields .PEAK_MAX_IN_BYTES , Fields .PEAK_MAX , new ByteSizeValue (pool .peakMax ));
225
236
237
+ builder .startObject (Fields .LAST_GC_STATS );
238
+ builder .humanReadableField (Fields .USED_IN_BYTES , Fields .USED , new ByteSizeValue (pool .getLastGcStats ().used ));
239
+ builder .humanReadableField (Fields .MAX_IN_BYTES , Fields .MAX , new ByteSizeValue (pool .getLastGcStats ().max ));
240
+ builder .field (Fields .USAGE_PERCENT , pool .getLastGcStats ().getUsagePercent ());
241
+ builder .endObject ();
242
+
226
243
builder .endObject ();
227
244
}
228
245
builder .endObject ();
@@ -299,7 +316,9 @@ static final class Fields {
299
316
static final String PEAK_USED_IN_BYTES = "peak_used_in_bytes" ;
300
317
static final String PEAK_MAX = "peak_max" ;
301
318
static final String PEAK_MAX_IN_BYTES = "peak_max_in_bytes" ;
302
-
319
+ static final String USAGE_PERCENT = "usage_percent" ;
320
+ static final String LAST_GC_STATS = "last_gc_stats" ;
321
+
303
322
static final String THREADS = "threads" ;
304
323
static final String COUNT = "count" ;
305
324
static final String PEAK_COUNT = "peak_count" ;
@@ -414,6 +433,48 @@ public int getPeakCount() {
414
433
return peakCount ;
415
434
}
416
435
}
436
+
437
+ /**
438
+ * Stores the memory usage after the Java virtual machine
439
+ * most recently expended effort in recycling unused objects
440
+ * in particular memory pool.
441
+ */
442
+ public static class MemoryPoolGcStats implements Writeable {
443
+
444
+ private final long used ;
445
+ private final long max ;
446
+
447
+ public MemoryPoolGcStats (long used , long max ) {
448
+ this .used = used ;
449
+ this .max = max ;
450
+ }
451
+
452
+ public MemoryPoolGcStats (StreamInput in ) throws IOException {
453
+ used = in .readVLong ();
454
+ max = in .readVLong ();
455
+ }
456
+
457
+ @ Override
458
+ public void writeTo (StreamOutput out ) throws IOException {
459
+ out .writeVLong (used );
460
+ out .writeVLong (max );
461
+ }
462
+
463
+ public ByteSizeValue getUsed () {
464
+ return new ByteSizeValue (used );
465
+ }
466
+
467
+ public ByteSizeValue getMax () {
468
+ return new ByteSizeValue (max );
469
+ }
470
+
471
+ public short getUsagePercent () {
472
+ if (max == 0 ) {
473
+ return -1 ;
474
+ }
475
+ return (short ) (used * 100 / max );
476
+ }
477
+ }
417
478
418
479
public static class MemoryPool implements Writeable {
419
480
@@ -422,13 +483,15 @@ public static class MemoryPool implements Writeable {
422
483
private final long max ;
423
484
private final long peakUsed ;
424
485
private final long peakMax ;
486
+ private final MemoryPoolGcStats lastGcStats ;
425
487
426
- public MemoryPool (String name , long used , long max , long peakUsed , long peakMax ) {
488
+ public MemoryPool (String name , long used , long max , long peakUsed , long peakMax , MemoryPoolGcStats lastGcStats ) {
427
489
this .name = name ;
428
490
this .used = used ;
429
491
this .max = max ;
430
492
this .peakUsed = peakUsed ;
431
493
this .peakMax = peakMax ;
494
+ this .lastGcStats = lastGcStats ;
432
495
}
433
496
434
497
public MemoryPool (StreamInput in ) throws IOException {
@@ -437,6 +500,11 @@ public MemoryPool(StreamInput in) throws IOException {
437
500
max = in .readVLong ();
438
501
peakUsed = in .readVLong ();
439
502
peakMax = in .readVLong ();
503
+ if (in .getVersion ().onOrAfter (Version .V_1_2_0 )) {
504
+ lastGcStats = new MemoryPoolGcStats (in );
505
+ } else {
506
+ lastGcStats = new MemoryPoolGcStats (0 , 0 );
507
+ }
440
508
}
441
509
442
510
@ Override
@@ -446,6 +514,9 @@ public void writeTo(StreamOutput out) throws IOException {
446
514
out .writeVLong (max );
447
515
out .writeVLong (peakUsed );
448
516
out .writeVLong (peakMax );
517
+ if (out .getVersion ().onOrAfter (Version .V_1_2_0 )) {
518
+ lastGcStats .writeTo (out );
519
+ }
449
520
}
450
521
451
522
public String getName () {
@@ -467,6 +538,13 @@ public ByteSizeValue getPeakUsed() {
467
538
public ByteSizeValue getPeakMax () {
468
539
return new ByteSizeValue (peakMax );
469
540
}
541
+
542
+ /**
543
+ * Returns the heap usage after last garbage collection cycle
544
+ */
545
+ public MemoryPoolGcStats getLastGcStats () {
546
+ return lastGcStats ;
547
+ }
470
548
}
471
549
472
550
public static class Mem implements Writeable , Iterable <MemoryPool > {
0 commit comments