Skip to content

Commit d30e663

Browse files
Force GC before direct memory measurements for ZGC compatibility
Generational ZGC (JDK 21 default) only processes PhantomReferences during major collections, which may not trigger during short test runs. This causes DirectByteBuffer Cleaners to not fire, leaving ~63MB of stale direct memory that inflates TOTAL_CAPACITY and fails the assertion. Force System.gc() via nodetool before each measurement to ensure a major collection runs and reference processing completes.
1 parent 8383bc5 commit d30e663

1 file changed

Lines changed: 17 additions & 3 deletions

File tree

largecolumn_test.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import pytest
22
import re
33
import logging
4+
import subprocess
5+
import time
46

57
from dtest import Tester
68

@@ -69,16 +71,28 @@ def test_cleanup(self):
6971
# Now run the full stack to warm up internal caches/pools
7072
LARGE_COLUMN_SIZE = 1024 * 1024 * 63
7173
self.stress_with_col_size(cluster, node1, LARGE_COLUMN_SIZE)
72-
after1stLargeStress = self.directbytes(node1)
74+
after1stLargeStress = self.directbytes_post_gc(node1)
7375
logger.info("After 1st large column stress, direct memory: {0}".format(after1stLargeStress))
7476

7577
# Now run the full stack to see how much memory is allocated for the second "large" columns request
7678
self.stress_with_col_size(cluster, node1, LARGE_COLUMN_SIZE)
77-
after2ndLargeStress = self.directbytes(node1)
79+
after2ndLargeStress = self.directbytes_post_gc(node1)
7880
logger.info("After 2nd large column stress, direct memory: {0}".format(after2ndLargeStress))
7981

8082
# We may allocate direct memory proportional to size of a request
8183
# but we want to ensure that when we do subsequent calls the used direct memory is not growing
82-
diff = int(after2ndLargeStress) - int(after1stLargeStress)
84+
diff = after2ndLargeStress - after1stLargeStress
8385
logger.info("Direct memory delta: {0}".format(diff))
8486
assert diff < LARGE_COLUMN_SIZE
87+
88+
def directbytes_post_gc(self, node):
89+
"""Trigger GC and wait for the Cleaner thread to release DirectByteBuffers.
90+
91+
Generational ZGC (JDK 21) only processes PhantomReferences during major
92+
collections which may not run during short tests. After GC, the Cleaner
93+
daemon thread decrements TOTAL_CAPACITY asynchronously, so we sleep to
94+
allow it to complete.
95+
"""
96+
subprocess.check_call(['jcmd', str(node.pid), 'GC.run'])
97+
time.sleep(3)
98+
return int(self.directbytes(node))

0 commit comments

Comments
 (0)