Skip to content

Commit 2c3ad08

Browse files
committed
patch
1 parent 76a7e43 commit 2c3ad08

File tree

1 file changed

+55
-23
lines changed

1 file changed

+55
-23
lines changed

src/java/org/apache/cassandra/service/GCInspector.java

Lines changed: 55 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.util.HashMap;
2727
import java.util.Map;
2828
import java.util.concurrent.TimeUnit;
29+
import java.util.concurrent.atomic.AtomicLong;
2930
import java.util.concurrent.atomic.AtomicReference;
3031

3132
import javax.management.MBeanServer;
@@ -54,36 +55,34 @@ public class GCInspector implements NotificationListener, GCInspectorMXBean
5455

5556
/*
5657
* The field from java.nio.Bits that tracks the total number of allocated
57-
* bytes of direct memory requires via ByteBuffer.allocateDirect that have not been GCed.
58+
* bytes of direct memory requested via ByteBuffer.allocateDirect that have not been GCed.
5859
*/
59-
final static Field BITS_TOTAL_CAPACITY;
60+
final static Field BITS_TOTAL_CAPACITY_JAVA_8;
61+
final static Field BITS_TOTAL_CAPACITY_JAVA_11;
6062

61-
6263
static
6364
{
64-
Field temp = null;
65+
Class<?> bitsClass = null;
66+
6567
try
6668
{
67-
Class<?> bitsClass = Class.forName("java.nio.Bits");
68-
Field f;
69-
try
70-
{
71-
f = bitsClass.getDeclaredField("totalCapacity");
72-
}
73-
catch (NoSuchFieldException ex)
74-
{
75-
// in Java11 it changed name to "TOTAL_CAPACITY"
76-
f = bitsClass.getDeclaredField("TOTAL_CAPACITY");
77-
}
78-
f.setAccessible(true);
79-
temp = f;
69+
bitsClass = Class.forName("java.nio.Bits");
8070
}
8171
catch (Throwable t)
8272
{
83-
logger.debug("Error accessing field of java.nio.Bits", t);
84-
//Don't care, will just return the dummy value -1 if we can't get at the field in this JVM
73+
logger.debug("Error returning class of java.nio.Bits", t);
74+
}
75+
76+
if (bitsClass != null)
77+
{
78+
BITS_TOTAL_CAPACITY_JAVA_8 = getField(bitsClass, "totalCapacity");
79+
BITS_TOTAL_CAPACITY_JAVA_11 = getField(bitsClass, "TOTAL_CAPACITY");
80+
}
81+
else
82+
{
83+
BITS_TOTAL_CAPACITY_JAVA_8 = null;
84+
BITS_TOTAL_CAPACITY_JAVA_11 = null;
8585
}
86-
BITS_TOTAL_CAPACITY = temp;
8786
}
8887

8988
static final class State
@@ -324,14 +323,47 @@ public double[] getAndResetStats()
324323

325324
private static long getAllocatedDirectMemory()
326325
{
327-
if (BITS_TOTAL_CAPACITY == null) return -1;
326+
long fieldValue = getFieldValue(BITS_TOTAL_CAPACITY_JAVA_8, true);
327+
328+
if (fieldValue == -1)
329+
fieldValue = getFieldValue(BITS_TOTAL_CAPACITY_JAVA_11, true);
330+
331+
return fieldValue;
332+
}
333+
334+
private static Field getField(Class<?> clazz, String fieldName)
335+
{
336+
try
337+
{
338+
Field field = clazz.getDeclaredField(fieldName);
339+
field.setAccessible(true);
340+
return field;
341+
}
342+
catch (Throwable t)
343+
{
344+
logger.trace("Error accessing field {} of {}", fieldName, clazz.getName(), t);
345+
// Return null to indicate failure
346+
return null;
347+
}
348+
}
349+
350+
/**
351+
* Retrieves the value of a Field, handling both regular long fields and AtomicLong fields.
352+
*
353+
* @param field the Field to retrieve the value from
354+
* @param isAtomicLong true if the field is an AtomicLong, false if it's a regular long
355+
* @return the field value, or -1 if retrieval fails or field is null.
356+
*/
357+
private static long getFieldValue(Field field, boolean isAtomicLong)
358+
{
359+
if (field == null) return -1;
328360
try
329361
{
330-
return BITS_TOTAL_CAPACITY.getLong(null);
362+
return isAtomicLong ? ((AtomicLong) field.get(null)).get() : field.getLong(null);
331363
}
332364
catch (Throwable t)
333365
{
334-
logger.trace("Error accessing field of java.nio.Bits", t);
366+
logger.trace("Error accessing field value of {}", field.getName(), t);
335367
//Don't care how or why we failed to get the value in this JVM. Return -1 to indicate failure
336368
return -1;
337369
}

0 commit comments

Comments
 (0)