Skip to content

Commit efbc502

Browse files
maolingsmiklosovic
authored andcommitted
Backport CASSANDRA-19022 to fix nodetool gcstats on max direct memory
patch by Stefan Miklosovic; reviewed by Brad Schoening for CASSANDRA-21037
1 parent 1a12cbb commit efbc502

File tree

1 file changed

+34
-12
lines changed

1 file changed

+34
-12
lines changed

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

Lines changed: 34 additions & 12 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;
@@ -60,23 +61,20 @@ public class GCInspector implements NotificationListener, GCInspectorMXBean
6061
*/
6162
final static Field BITS_TOTAL_CAPACITY;
6263

63-
6464
static
6565
{
66-
Field temp = null;
66+
Field totalTempField = null;
6767
try
6868
{
6969
Class<?> bitsClass = Class.forName("java.nio.Bits");
70-
Field f = bitsClass.getDeclaredField("TOTAL_CAPACITY");
71-
f.setAccessible(true);
72-
temp = f;
70+
totalTempField = getField(bitsClass, "TOTAL_CAPACITY");
7371
}
7472
catch (Throwable t)
7573
{
7674
logger.debug("Error accessing field of java.nio.Bits", t);
7775
//Don't care, will just return the dummy value -1 if we can't get at the field in this JVM
7876
}
79-
BITS_TOTAL_CAPACITY = temp;
77+
BITS_TOTAL_CAPACITY = totalTempField;
8078
}
8179

8280
static final class State
@@ -303,28 +301,52 @@ public State getTotalSinceLastCheck()
303301
public double[] getAndResetStats()
304302
{
305303
State state = getTotalSinceLastCheck();
306-
double[] r = new double[7];
304+
double[] r = new double[9];
307305
r[0] = TimeUnit.NANOSECONDS.toMillis(nanoTime() - state.startNanos);
308306
r[1] = state.maxRealTimeElapsed;
309307
r[2] = state.totalRealTimeElapsed;
310308
r[3] = state.sumSquaresRealTimeElapsed;
311309
r[4] = state.totalBytesReclaimed;
312310
r[5] = state.count;
313-
r[6] = getAllocatedDirectMemory();
311+
r[6] = getTotalDirectMemory();
314312

315313
return r;
316314
}
317315

318-
private static long getAllocatedDirectMemory()
316+
private static long getTotalDirectMemory()
319317
{
320-
if (BITS_TOTAL_CAPACITY == null) return -1;
318+
return getFieldValue(BITS_TOTAL_CAPACITY, true);
319+
}
320+
321+
private static Field getField(Class<?> clazz, String fieldName)
322+
{
323+
try
324+
{
325+
Field field = clazz.getDeclaredField(fieldName);
326+
field.setAccessible(true);
327+
return field;
328+
}
329+
catch (Throwable t)
330+
{
331+
logger.trace("Error accessing field {} of {}", fieldName, clazz.getName(), t);
332+
// Return null to indicate failure
333+
return null;
334+
}
335+
}
336+
337+
/**
338+
* This method works well with JDK 11/17
339+
*/
340+
private static long getFieldValue(Field field, boolean isAtomicLong)
341+
{
342+
if (field == null) return -1;
321343
try
322344
{
323-
return BITS_TOTAL_CAPACITY.getLong(null);
345+
return isAtomicLong ? ((AtomicLong) field.get(null)).get() : field.getLong(null);
324346
}
325347
catch (Throwable t)
326348
{
327-
logger.trace("Error accessing field of java.nio.Bits", t);
349+
logger.trace("Error accessing field value of {}", field.getName(), t);
328350
//Don't care how or why we failed to get the value in this JVM. Return -1 to indicate failure
329351
return -1;
330352
}

0 commit comments

Comments
 (0)