mirror of https://github.com/apache/cassandra
Merge branch 'cassandra-4.0' into cassandra-4.1
This commit is contained in:
commit
73648c8215
|
|
@ -2,6 +2,7 @@
|
|||
* ReadCommandController should close fast to avoid deadlock when building secondary index (CASSANDRA-19564)
|
||||
* Redact security-sensitive information in system_views.settings (CASSANDRA-20856)
|
||||
Merged from 4.0:
|
||||
* Backport fix to nodetool gcstats output for direct memory (CASSANDRA-21037)
|
||||
* ArrayIndexOutOfBoundsException with repaired data tracking and counters (CASSANDRA-20871)
|
||||
* Fix cleanup of old incremental repair sessions in case of owned token range changes or a table deleting (CASSANDRA-20877)
|
||||
* Fix memory leak in BufferPoolAllocator when a capacity needs to be extended (CASSANDRA-20753)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import java.util.Arrays;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.management.MBeanServer;
|
||||
|
|
@ -56,36 +57,34 @@ public class GCInspector implements NotificationListener, GCInspectorMXBean
|
|||
|
||||
/*
|
||||
* The field from java.nio.Bits that tracks the total number of allocated
|
||||
* bytes of direct memory requires via ByteBuffer.allocateDirect that have not been GCed.
|
||||
* bytes of direct memory requested via ByteBuffer.allocateDirect that have not been GCed.
|
||||
*/
|
||||
final static Field BITS_TOTAL_CAPACITY;
|
||||
final static Field BITS_TOTAL_CAPACITY_JAVA_8;
|
||||
final static Field BITS_TOTAL_CAPACITY_JAVA_11;
|
||||
|
||||
|
||||
static
|
||||
{
|
||||
Field temp = null;
|
||||
Class<?> bitsClass = null;
|
||||
|
||||
try
|
||||
{
|
||||
Class<?> bitsClass = Class.forName("java.nio.Bits");
|
||||
Field f;
|
||||
try
|
||||
{
|
||||
f = bitsClass.getDeclaredField("totalCapacity");
|
||||
}
|
||||
catch (NoSuchFieldException ex)
|
||||
{
|
||||
// in Java11 it changed name to "TOTAL_CAPACITY"
|
||||
f = bitsClass.getDeclaredField("TOTAL_CAPACITY");
|
||||
}
|
||||
f.setAccessible(true);
|
||||
temp = f;
|
||||
bitsClass = Class.forName("java.nio.Bits");
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
logger.debug("Error accessing field of java.nio.Bits", t);
|
||||
//Don't care, will just return the dummy value -1 if we can't get at the field in this JVM
|
||||
logger.debug("Error returning class of java.nio.Bits", t);
|
||||
}
|
||||
|
||||
if (bitsClass != null)
|
||||
{
|
||||
BITS_TOTAL_CAPACITY_JAVA_8 = getField(bitsClass, "totalCapacity");
|
||||
BITS_TOTAL_CAPACITY_JAVA_11 = getField(bitsClass, "TOTAL_CAPACITY");
|
||||
}
|
||||
else
|
||||
{
|
||||
BITS_TOTAL_CAPACITY_JAVA_8 = null;
|
||||
BITS_TOTAL_CAPACITY_JAVA_11 = null;
|
||||
}
|
||||
BITS_TOTAL_CAPACITY = temp;
|
||||
}
|
||||
|
||||
static final class State
|
||||
|
|
@ -326,14 +325,47 @@ public class GCInspector implements NotificationListener, GCInspectorMXBean
|
|||
|
||||
private static long getAllocatedDirectMemory()
|
||||
{
|
||||
if (BITS_TOTAL_CAPACITY == null) return -1;
|
||||
long fieldValue = getFieldValue(BITS_TOTAL_CAPACITY_JAVA_8, true);
|
||||
|
||||
if (fieldValue == -1)
|
||||
fieldValue = getFieldValue(BITS_TOTAL_CAPACITY_JAVA_11, true);
|
||||
|
||||
return fieldValue;
|
||||
}
|
||||
|
||||
private static Field getField(Class<?> clazz, String fieldName)
|
||||
{
|
||||
try
|
||||
{
|
||||
return BITS_TOTAL_CAPACITY.getLong(null);
|
||||
Field field = clazz.getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
return field;
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
logger.trace("Error accessing field of java.nio.Bits", t);
|
||||
logger.trace("Error accessing field {} of {}", fieldName, clazz.getName(), t);
|
||||
// Return null to indicate failure
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the value of a Field, handling both regular long fields and AtomicLong fields.
|
||||
*
|
||||
* @param field the Field to retrieve the value from
|
||||
* @param isAtomicLong true if the field is an AtomicLong, false if it's a regular long
|
||||
* @return the field value, or -1 if retrieval fails or field is null.
|
||||
*/
|
||||
private static long getFieldValue(Field field, boolean isAtomicLong)
|
||||
{
|
||||
if (field == null) return -1;
|
||||
try
|
||||
{
|
||||
return isAtomicLong ? ((AtomicLong) field.get(null)).get() : field.getLong(null);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
logger.trace("Error accessing field value of {}", field.getName(), t);
|
||||
//Don't care how or why we failed to get the value in this JVM. Return -1 to indicate failure
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue