Skip to content

Commit 125faab

Browse files
jbachorikclaude
andcommitted
Drop free event tracking from native malloc profiler
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent f70abcb commit 125faab

10 files changed

Lines changed: 54 additions & 236 deletions

File tree

ddprof-lib/src/main/cpp/arguments.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -380,13 +380,6 @@ Error Arguments::parse(const char *args) {
380380
msg = "nativemem must be >= 0";
381381
}
382382

383-
CASE("nofree")
384-
if (value != NULL && (value[0] == 'f' || value[0] == 'n' || value[0] == '0')) {
385-
_nofree = false;
386-
} else {
387-
_nofree = true;
388-
}
389-
390383
DEFAULT()
391384
if (_unknown_arg == NULL)
392385
_unknown_arg = arg;

ddprof-lib/src/main/cpp/arguments.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,6 @@ class Arguments {
177177
bool _record_heap_usage;
178178
bool _gc_generations;
179179
long _nativemem;
180-
bool _nofree;
181180
int _jstackdepth;
182181
int _safe_mode;
183182
StackWalkFeatures _features;
@@ -213,7 +212,6 @@ class Arguments {
213212
_record_heap_usage(false),
214213
_gc_generations(false),
215214
_nativemem(-1),
216-
_nofree(true),
217215
_jstackdepth(DEFAULT_JSTACKDEPTH),
218216
_safe_mode(0),
219217
_features{1, 1, 1, 1, 1, 1},

ddprof-lib/src/main/cpp/flightRecorder.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1578,15 +1578,13 @@ void Recording::recordAllocation(RecordingBuffer *buf, int tid,
15781578
void Recording::recordMallocSample(Buffer *buf, int tid, u64 call_trace_id,
15791579
MallocEvent *event) {
15801580
int start = buf->skip(1);
1581-
buf->putVar64(event->_size != 0 ? T_MALLOC : T_FREE);
1581+
buf->putVar64(T_MALLOC);
15821582
buf->putVar64(event->_start_time);
15831583
buf->putVar32(tid);
15841584
buf->putVar64(call_trace_id);
15851585
buf->putVar64(event->_address);
1586-
if (event->_size != 0) {
1587-
buf->putVar64(event->_size);
1588-
buf->putFloat(event->_weight);
1589-
}
1586+
buf->putVar64(event->_size);
1587+
buf->putFloat(event->_weight);
15901588
writeContext(buf, Contexts::get());
15911589
writeEventSizePrefix(buf, start);
15921590
flushIfNeeded(buf);

ddprof-lib/src/main/cpp/jfrMetadata.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -299,16 +299,6 @@ void JfrMetadata::initialize(
299299
<< field("localRootSpanId", T_LONG, "Local Root Span ID") ||
300300
contextAttributes)
301301

302-
<< (type("profiler.Free", T_FREE, "free")
303-
<< category("Java Virtual Machine", "Native Memory")
304-
<< field("startTime", T_LONG, "Start Time", F_TIME_TICKS)
305-
<< field("eventThread", T_THREAD, "Event Thread", F_CPOOL)
306-
<< field("stackTrace", T_STACK_TRACE, "Stack Trace", F_CPOOL)
307-
<< field("address", T_LONG, "Address", F_ADDRESS)
308-
<< field("spanId", T_LONG, "Span ID")
309-
<< field("localRootSpanId", T_LONG, "Local Root Span ID") ||
310-
contextAttributes)
311-
312302
<< (type("jdk.OSInformation", T_OS_INFORMATION, "OS Information")
313303
<< category("Operating System")
314304
<< field("startTime", T_LONG, "Start Time", F_TIME_TICKS)

ddprof-lib/src/main/cpp/jfrMetadata.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ enum JfrType {
8080
T_DATADOG_COUNTER = 125,
8181
T_UNWIND_FAILURE = 126,
8282
T_MALLOC = 127,
83-
T_FREE = 128,
8483
T_ANNOTATION = 200,
8584
T_LABEL = 201,
8685
T_CATEGORY = 202,

ddprof-lib/src/main/cpp/mallocTracer.cpp

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -62,24 +62,14 @@ void* calloc_hook_dummy(size_t num, size_t size) {
6262

6363
extern "C" void* realloc_hook(void* addr, size_t size) {
6464
void* ret = _orig_realloc(addr, size);
65-
if (MallocTracer::running()) {
66-
// On POSIX, realloc(ptr, 0) may return NULL and free ptr.
67-
// Only record the free if allocation didn't simply fail (size > 0 with NULL ret = ENOMEM).
68-
if (addr && !MallocTracer::nofree() && (ret != NULL || size == 0)) {
69-
MallocTracer::recordFree(addr);
70-
}
71-
if (ret != NULL && size > 0) {
72-
MallocTracer::recordMalloc(ret, size);
73-
}
65+
if (MallocTracer::running() && ret != NULL && size > 0) {
66+
MallocTracer::recordMalloc(ret, size);
7467
}
7568
return ret;
7669
}
7770

7871
extern "C" void free_hook(void* addr) {
7972
_orig_free(addr);
80-
if (MallocTracer::running() && !MallocTracer::nofree() && addr) {
81-
MallocTracer::recordFree(addr);
82-
}
8373
}
8474

8575
extern "C" int posix_memalign_hook(void** memptr, size_t alignment, size_t size) {
@@ -105,7 +95,6 @@ extern "C" void* aligned_alloc_hook(size_t alignment, size_t size) {
10595
}
10696

10797
volatile u64 MallocTracer::_interval;
108-
bool MallocTracer::_nofree;
10998
volatile u64 MallocTracer::_bytes_until_sample;
11099
u64 MallocTracer::_configured_interval;
111100
volatile u64 MallocTracer::_sample_count;
@@ -298,22 +287,12 @@ void MallocTracer::recordMalloc(void* address, size_t size) {
298287
}
299288
}
300289

301-
void MallocTracer::recordFree(void* address) {
302-
MallocEvent event;
303-
event._start_time = TSC::ticks();
304-
event._address = (uintptr_t)address;
305-
event._size = 0;
306-
307-
Profiler::instance()->recordSample(NULL, 0, OS::threadId(), BCI_NATIVE_MALLOC, 0, &event);
308-
}
309-
310290
Error MallocTracer::start(Arguments& args) {
311291
_configured_interval = args._nativemem > 0 ? args._nativemem : 0;
312292
_interval = _configured_interval;
313-
_nofree = args._nofree;
314293
_bytes_until_sample = _configured_interval > 1 ? nextPoissonInterval() : 0;
315294
_sample_count = 0;
316-
_last_config_update_ts = OS::nanotime();
295+
__atomic_store_n(&_last_config_update_ts, OS::nanotime(), __ATOMIC_RELEASE);
317296

318297
if (!_initialized) {
319298
initialize();

ddprof-lib/src/main/cpp/mallocTracer.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
class MallocTracer : public Engine {
1616
private:
1717
static volatile u64 _interval;
18-
static bool _nofree;
1918
static volatile u64 _bytes_until_sample;
2019

2120
static u64 _configured_interval;
@@ -53,12 +52,7 @@ class MallocTracer : public Engine {
5352
}
5453
}
5554

56-
static inline bool nofree() {
57-
return _nofree;
58-
}
59-
6055
static void recordMalloc(void* address, size_t size);
61-
static void recordFree(void* address);
6256
};
6357

6458
#endif // _MALLOCTRACER_H

ddprof-test/src/test/java/com/datadoghq/profiler/nativemem/NativememProfilerTest.java

Lines changed: 1 addition & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,14 @@
2020

2121
import java.nio.ByteBuffer;
2222
import java.util.ArrayList;
23-
import java.util.HashSet;
2423
import java.util.List;
25-
import java.util.Set;
2624

2725
import static org.junit.jupiter.api.Assertions.assertTrue;
2826
import static org.openjdk.jmc.common.item.Attribute.attr;
2927
import static org.openjdk.jmc.common.unit.UnitLookup.ADDRESS;
3028

3129
/**
32-
* Smoke tests for native memory (malloc/free) profiling.
30+
* Smoke tests for native memory (malloc) profiling.
3331
*
3432
* <p>Runs with {@code cstack=vm} and {@code cstack=vmx}. In {@code vmx} mode the
3533
* stack trace is expected to contain {@code allocateDirect} because the mixed-mode
@@ -94,57 +92,4 @@ public void shouldRecordMallocSamples() throws InterruptedException {
9492
buffers.clear(); // keep alive until after stop
9593
}
9694

97-
@RetryTest(3)
98-
@TestTemplate
99-
@ValueSource(strings = {"vm", "vmx"})
100-
public void shouldRecordFreeEvents() throws InterruptedException {
101-
Assumptions.assumeFalse(isAsan() || isTsan());
102-
103-
// Allocate and immediately abandon so the GC Cleaner will call free()
104-
for (int i = 0; i < 1000; i++) {
105-
ByteBuffer.allocateDirect(1024);
106-
}
107-
for (int attempt = 0; attempt < 5; attempt++) {
108-
System.gc();
109-
Thread.sleep(200);
110-
}
111-
112-
stopProfiler();
113-
114-
IItemCollection mallocEvents = verifyEvents("profiler.Malloc");
115-
IItemCollection freeEvents = verifyEvents("profiler.Free");
116-
117-
// Collect all recorded malloc addresses
118-
Set<Long> mallocAddresses = new HashSet<>();
119-
for (IItemIterable items : mallocEvents) {
120-
IMemberAccessor<IQuantity, IItem> addrAccessor = MALLOC_ADDRESS.getAccessor(items.getType());
121-
if (addrAccessor == null) {
122-
continue;
123-
}
124-
for (IItem item : items) {
125-
IQuantity addr = addrAccessor.getMember(item);
126-
if (addr != null) {
127-
mallocAddresses.add(addr.longValue());
128-
}
129-
}
130-
}
131-
132-
// At least one free event address must match a previously recorded malloc address
133-
boolean foundCorrelation = false;
134-
outer:
135-
for (IItemIterable items : freeEvents) {
136-
IMemberAccessor<IQuantity, IItem> addrAccessor = MALLOC_ADDRESS.getAccessor(items.getType());
137-
if (addrAccessor == null) {
138-
continue;
139-
}
140-
for (IItem item : items) {
141-
IQuantity addr = addrAccessor.getMember(item);
142-
if (addr != null && mallocAddresses.contains(addr.longValue())) {
143-
foundCorrelation = true;
144-
break outer;
145-
}
146-
}
147-
}
148-
assertTrue(foundCorrelation, "expected at least one free event whose address matches a recorded malloc");
149-
}
15095
}

ddprof-test/src/test/java/com/datadoghq/profiler/nativemem/NofreeNativememProfilerTest.java

Lines changed: 0 additions & 61 deletions
This file was deleted.

0 commit comments

Comments
 (0)