Skip to content

Commit 7d1e329

Browse files
authored
Enable live heap profiling by default on safe JVM versions (#11039)
Enable live heap profiling by default on safe JVM versions Adds unified config key `profiling.liveheap.enabled` that auto-detects safe systems (isJmethodIDSafe || isOldObjectSampleAvailable) and enables live heap profiling by default. Ddprof native library is preferred with JFR OldObjectSample as fallback. New `profiling.liveheap.jfr.enabled` replaces deprecated `profiling.heap.enabled` with context-aware deprecation warnings. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Merge branch 'master' into jb/live_heap_default Fix live heap enablement logic for Java 8 and unsafe JVM versions - On Java 8, neither ddprof MEMLEAK (requires Java 11+) nor JFR OldObjectSample is available; explicitly enabling profiling.heap.enabled now logs a warning instead of silently enabling an unsupported event - ddprofLikelyActive heuristic uses isJmethodIDSafe() as the default for the liveheap flag (was hardcoded true), matching ddprof's own resolution and preventing false disablement of OldObjectSample on Java 11.0.12-11.0.22 and 17.0.3-17.0.10 - Fix testHeapProfilerIsStillOverriddenThroughConfig to expect isOldObjectSampleAvailable() instead of unconditional true Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: jaroslav.bachorik <jaroslav.bachorik@datadoghq.com>
1 parent 51998da commit 7d1e329

File tree

9 files changed

+228
-39
lines changed

9 files changed

+228
-39
lines changed

dd-java-agent/agent-profiling/profiling-controller-openjdk/src/main/java/com/datadog/profiling/controller/openjdk/OpenJdkController.java

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -192,10 +192,36 @@ public OpenJdkController(final ConfigProvider configProvider)
192192

193193
// Toggle settings from config
194194

195-
if (configProvider.getBoolean(
196-
ProfilingConfig.PROFILING_HEAP_ENABLED, ProfilingConfig.PROFILING_HEAP_ENABLED_DEFAULT)) {
197-
log.debug("Enabling OldObjectSample JFR event with the config.");
198-
recordingSettings.put("jdk.OldObjectSample#enabled", "true");
195+
// Unified live heap (profiling.heap.enabled): when explicitly disabled, turn off
196+
// OldObjectSample. When enabled (or default), if ddprof is likely handling live heap,
197+
// proactively disable OldObjectSample to avoid double collection.
198+
// disableOverriddenEvents() at recording start is the definitive safety net,
199+
// but we disable here too so the settings map is consistent from the start.
200+
if (!configProvider.getBoolean(
201+
ProfilingConfig.PROFILING_HEAP_ENABLED, isLiveHeapProfilingSafe())) {
202+
disableEvent(recordingSettings, "jdk.OldObjectSample", "live heap profiling is disabled");
203+
} else {
204+
// ddprof live heap requires Java 11+ (JVMTI Allocation Sampler)
205+
// isJmethodIDSafe() matches ddprof's own default for liveheap: it only enables
206+
// MEMLEAK mode by default on versions where jmethodID is safe.
207+
boolean ddprofLikelyActive =
208+
isJavaVersionAtLeast(11)
209+
&& configProvider.getBoolean(
210+
ProfilingConfig.PROFILING_DATADOG_PROFILER_LIVEHEAP_ENABLED, isJmethodIDSafe())
211+
&& configProvider.getBoolean(
212+
ProfilingConfig.PROFILING_DATADOG_PROFILER_ENABLED, true);
213+
if (ddprofLikelyActive) {
214+
disableEvent(
215+
recordingSettings,
216+
"jdk.OldObjectSample",
217+
"ddprof live heap profiling is expected to handle live heap data");
218+
} else if (isOldObjectSampleAvailable()) {
219+
enableEvent(recordingSettings, "jdk.OldObjectSample", "heap profiling is enabled");
220+
} else if (configProvider.getBoolean(ProfilingConfig.PROFILING_HEAP_ENABLED, false)) {
221+
log.warn(
222+
"Live heap profiling was explicitly requested but is not supported on this JVM version;"
223+
+ " no heap profiling data will be collected.");
224+
}
199225
}
200226

201227
if (configProvider.getBoolean(
@@ -240,9 +266,8 @@ ProfilingConfig.PROFILING_ALLOCATION_ENABLED, isObjectAllocationSampleAvailable(
240266

241267
// Warn users for expensive events
242268

243-
if (!isOldObjectSampleAvailable()
244-
&& isEventEnabled(recordingSettings, "jdk.OldObjectSample#enabled")) {
245-
log.warn("Inexpensive heap profiling is not supported for this JDK but is enabled.");
269+
if (!isOldObjectSampleAvailable() && isEventEnabled(recordingSettings, "jdk.OldObjectSample")) {
270+
log.warn("JFR based live heap profiling is not supported for this JDK but is enabled.");
246271
}
247272

248273
if (isEventEnabled(recordingSettings, "jdk.ObjectAllocationInNewTLAB")

dd-java-agent/agent-profiling/profiling-controller-openjdk/src/test/java/com/datadog/profiling/controller/openjdk/OpenJdkControllerTest.java

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616

1717
import com.datadog.profiling.controller.ControllerContext;
1818
import com.datadog.profiling.controller.jfr.JfpUtilsTest;
19+
import com.datadog.profiling.utils.ProfilingMode;
1920
import datadog.environment.JavaVirtualMachine;
2021
import datadog.trace.api.profiling.RecordingData;
2122
import datadog.trace.bootstrap.config.provider.ConfigProvider;
23+
import java.util.EnumSet;
2224
import java.util.Properties;
2325
import jdk.jfr.Recording;
2426
import org.junit.jupiter.api.BeforeAll;
@@ -94,6 +96,8 @@ public void testHeapProfilerIsStillOverriddenOnUnsupportedVersion() throws Excep
9496
public void testHeapProfilerIsStillOverriddenThroughConfig() throws Exception {
9597
Properties props = getConfigProperties();
9698
props.put(PROFILING_HEAP_ENABLED, "true");
99+
// Disable ddprof so OldObjectSample is not proactively disabled
100+
props.put(PROFILING_DATADOG_PROFILER_ENABLED, "false");
97101

98102
ConfigProvider configProvider = ConfigProvider.withPropertiesOverride(props);
99103

@@ -102,10 +106,11 @@ public void testHeapProfilerIsStillOverriddenThroughConfig() throws Exception {
102106
((OpenJdkRecordingData)
103107
controller.createRecording(TEST_NAME, new ControllerContext().snapshot()).stop())
104108
.getRecording()) {
105-
if (!isOldObjectSampleAvailable()) {
106-
assertEquals(
107-
true, Boolean.parseBoolean(recording.getSettings().get("jdk.OldObjectSample#enabled")));
108-
}
109+
// On JVMs where OldObjectSample is not available (e.g. Java 8), explicitly enabling heap
110+
// profiling has no effect — the event cannot be safely enabled.
111+
assertEquals(
112+
isOldObjectSampleAvailable(),
113+
Boolean.parseBoolean(recording.getSettings().get("jdk.OldObjectSample#enabled")));
109114
}
110115
}
111116

@@ -234,6 +239,43 @@ public void testNativeProfilerIsStillOverriddenOnUnsupportedVersion() throws Exc
234239
}
235240
}
236241

242+
@Test
243+
public void testOldObjectSampleDisabledWhenDdprofMemleakActive() throws Exception {
244+
Properties props = getConfigProperties();
245+
props.put(PROFILING_DATADOG_PROFILER_ENABLED, "true");
246+
247+
ConfigProvider configProvider = ConfigProvider.withPropertiesOverride(props);
248+
249+
ControllerContext context = new ControllerContext();
250+
context.setDatadogProfilerEnabled(true);
251+
context.setDatadogProfilingModes(EnumSet.of(ProfilingMode.MEMLEAK));
252+
253+
OpenJdkController controller = new OpenJdkController(configProvider);
254+
try (final Recording recording =
255+
((OpenJdkRecordingData) controller.createRecording(TEST_NAME, context.snapshot()).stop())
256+
.getRecording()) {
257+
assertFalse(Boolean.parseBoolean(recording.getSettings().get("jdk.OldObjectSample#enabled")));
258+
}
259+
}
260+
261+
@Test
262+
public void testUnifiedFlagDisabledTurnsOffOldObjectSample() throws Exception {
263+
Properties props = getConfigProperties();
264+
props.put(PROFILING_HEAP_ENABLED, "false");
265+
266+
ConfigProvider configProvider = ConfigProvider.withPropertiesOverride(props);
267+
268+
OpenJdkController controller = new OpenJdkController(configProvider);
269+
RecordingData data =
270+
controller.createRecording(TEST_NAME, new ControllerContext().snapshot()).stop();
271+
assertTrue(data instanceof OpenJdkRecordingData);
272+
try (final Recording recording = ((OpenJdkRecordingData) data).getRecording()) {
273+
assertFalse(
274+
Boolean.parseBoolean(recording.getSettings().get("jdk.OldObjectSample#enabled")),
275+
"OldObjectSample should be disabled when unified live heap flag is false");
276+
}
277+
}
278+
237279
private static Properties getConfigProperties() {
238280
Properties props = new Properties();
239281
// make sure the async profiler is not force-enabled

dd-java-agent/agent-profiling/profiling-controller/src/main/java/com/datadog/profiling/controller/ProfilerFlareReporter.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,19 @@ private String getProfilerConfig() {
157157
ProfilingConfig.PROFILING_DIRECT_ALLOCATION_SAMPLE_LIMIT_DEFAULT);
158158

159159
sb.append("\n=== Heap Profiling ===\n");
160+
boolean heapDefault = ProfilingSupport.isLiveHeapProfilingSafe();
160161
appendConfig(
161162
sb,
162163
"Heap Profiling Enabled",
163-
configProvider.getBoolean(
164-
ProfilingConfig.PROFILING_HEAP_ENABLED, ProfilingConfig.PROFILING_HEAP_ENABLED_DEFAULT),
165-
ProfilingConfig.PROFILING_HEAP_ENABLED_DEFAULT);
164+
configProvider.getBoolean(ProfilingConfig.PROFILING_HEAP_ENABLED, heapDefault),
165+
heapDefault);
166+
appendConfig(
167+
sb,
168+
"DDProf Live Heap Enabled",
169+
configProvider.getString(ProfilingConfig.PROFILING_DATADOG_PROFILER_LIVEHEAP_ENABLED),
170+
null);
171+
appendConfig(
172+
sb, "JFR OldObjectSample Available", ProfilingSupport.isOldObjectSampleAvailable(), false);
166173
appendConfig(
167174
sb,
168175
"Heap Histogram Enabled",

dd-java-agent/agent-profiling/profiling-controller/src/main/java/com/datadog/profiling/controller/ProfilerSettingsSupport.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ protected ProfilerSettingsSupport(
140140
ProfilingSupport.isObjectAllocationSampleAvailable());
141141
heapProfilingEnabled =
142142
configProvider.getBoolean(
143-
ProfilingConfig.PROFILING_HEAP_ENABLED, ProfilingConfig.PROFILING_HEAP_ENABLED_DEFAULT);
143+
ProfilingConfig.PROFILING_HEAP_ENABLED, ProfilingSupport.isLiveHeapProfilingSafe());
144144
startForceFirst =
145145
configProvider.getBoolean(
146146
ProfilingConfig.PROFILING_START_FORCE_FIRST,

dd-java-agent/agent-profiling/profiling-controller/src/main/java/com/datadog/profiling/controller/ProfilingSupport.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,41 @@
44
import static datadog.environment.JavaVirtualMachine.isJavaVersionAtLeast;
55
import static datadog.environment.JavaVirtualMachine.isOracleJDK8;
66

7+
import datadog.environment.JavaVirtualMachine;
8+
79
public class ProfilingSupport {
810

11+
/**
12+
* Checks whether jmethodID handling is safe on the current JVM version. Unsafe versions can cause
13+
* crashes due to <a href="https://bugs.openjdk.org/browse/JDK-8313816">JDK-8313816</a>.
14+
*/
15+
public static boolean isJmethodIDSafe() {
16+
if (isJavaVersionAtLeast(22)) {
17+
return true;
18+
}
19+
switch (JavaVirtualMachine.getLangVersion()) {
20+
case "8":
21+
return true;
22+
case "11":
23+
return isJavaVersionAtLeast(11, 0, 23);
24+
case "17":
25+
return isJavaVersionAtLeast(17, 0, 11);
26+
case "21":
27+
return isJavaVersionAtLeast(21, 0, 3);
28+
default:
29+
return false;
30+
}
31+
}
32+
33+
/**
34+
* Checks whether any live heap profiling mechanism is safe to enable on the current platform.
35+
* Returns true if at least one of ddprof native (jmethodID safe) or JFR OldObjectSample is
36+
* available.
37+
*/
38+
public static boolean isLiveHeapProfilingSafe() {
39+
return isJmethodIDSafe() || isOldObjectSampleAvailable();
40+
}
41+
942
public static boolean isOldObjectSampleAvailable() {
1043
if (isOracleJDK8()) {
1144
return false;

dd-java-agent/agent-profiling/profiling-ddprof/src/main/java/com/datadog/profiling/ddprof/DatadogProfilerConfig.java

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.datadog.profiling.ddprof;
22

3+
import static com.datadog.profiling.controller.ProfilingSupport.isOldObjectSampleAvailable;
34
import static datadog.environment.JavaVirtualMachine.isJ9;
45
import static datadog.trace.api.config.ProfilingConfig.PROFILING_ALLOCATION_ENABLED;
56
import static datadog.trace.api.config.ProfilingConfig.PROFILING_CONTEXT_ATTRIBUTES;
@@ -20,7 +21,6 @@
2021
import static datadog.trace.api.config.ProfilingConfig.PROFILING_DATADOG_PROFILER_LIVEHEAP_CAPACITY;
2122
import static datadog.trace.api.config.ProfilingConfig.PROFILING_DATADOG_PROFILER_LIVEHEAP_CAPACITY_DEFAULT;
2223
import static datadog.trace.api.config.ProfilingConfig.PROFILING_DATADOG_PROFILER_LIVEHEAP_ENABLED;
23-
import static datadog.trace.api.config.ProfilingConfig.PROFILING_DATADOG_PROFILER_LIVEHEAP_ENABLED_DEFAULT;
2424
import static datadog.trace.api.config.ProfilingConfig.PROFILING_DATADOG_PROFILER_LIVEHEAP_INTERVAL;
2525
import static datadog.trace.api.config.ProfilingConfig.PROFILING_DATADOG_PROFILER_LIVEHEAP_SAMPLE_PERCENT;
2626
import static datadog.trace.api.config.ProfilingConfig.PROFILING_DATADOG_PROFILER_LIVEHEAP_SAMPLE_PERCENT_DEFAULT;
@@ -43,6 +43,7 @@
4343
import static datadog.trace.api.config.ProfilingConfig.PROFILING_DATADOG_PROFILER_WALL_ENABLED;
4444
import static datadog.trace.api.config.ProfilingConfig.PROFILING_DATADOG_PROFILER_WALL_INTERVAL;
4545
import static datadog.trace.api.config.ProfilingConfig.PROFILING_DATADOG_PROFILER_WALL_INTERVAL_DEFAULT;
46+
import static datadog.trace.api.config.ProfilingConfig.PROFILING_HEAP_ENABLED;
4647
import static datadog.trace.api.config.ProfilingConfig.PROFILING_HEAP_TRACK_GENERATIONS;
4748
import static datadog.trace.api.config.ProfilingConfig.PROFILING_HEAP_TRACK_GENERATIONS_DEFAULT;
4849
import static datadog.trace.api.config.ProfilingConfig.PROFILING_QUEUEING_TIME_ENABLED;
@@ -52,6 +53,7 @@
5253
import static datadog.trace.api.config.ProfilingConfig.PROFILING_ULTRA_MINIMAL;
5354
import static datadog.trace.api.config.TraceInstrumentationConfig.TRACE_ENABLED;
5455

56+
import com.datadog.profiling.controller.ProfilingSupport;
5557
import datadog.environment.JavaVirtualMachine;
5658
import datadog.trace.api.config.ProfilingConfig;
5759
import datadog.trace.bootstrap.config.provider.ConfigProvider;
@@ -165,26 +167,12 @@ public static boolean getWallContextFilter(ConfigProvider configProvider) {
165167
PROFILING_DATADOG_PROFILER_WALL_CONTEXT_FILTER_DEFAULT);
166168
}
167169

168-
private static boolean isJmethodIDSafe() {
169-
// see https://bugs.openjdk.org/browse/JDK-8313816
170-
if (JavaVirtualMachine.isJavaVersionAtLeast(22)) {
171-
// any version after 22 should be safe
172-
return true;
173-
}
174-
switch (JavaVirtualMachine.getLangVersion()) {
175-
case "8":
176-
// Java 8 is not affected by the jmethodID issue
177-
return true;
178-
case "11":
179-
return JavaVirtualMachine.isJavaVersionAtLeast(11, 0, 23);
180-
case "17":
181-
return JavaVirtualMachine.isJavaVersionAtLeast(17, 0, 11);
182-
case "21":
183-
return JavaVirtualMachine.isJavaVersionAtLeast(21, 0, 3);
184-
default:
185-
// any other non-LTS version should be considered unsafe
186-
return false;
187-
}
170+
static boolean isJmethodIDSafe() {
171+
return ProfilingSupport.isJmethodIDSafe();
172+
}
173+
174+
static boolean isMemoryLeakProfilingSafe() {
175+
return ProfilingSupport.isLiveHeapProfilingSafe();
188176
}
189177

190178
public static boolean isAllocationProfilingEnabled(ConfigProvider configProvider) {
@@ -223,16 +211,29 @@ public static int getAllocationInterval() {
223211
}
224212

225213
public static boolean isMemoryLeakProfilingEnabled(ConfigProvider configProvider) {
226-
boolean isSafe = isJmethodIDSafe();
214+
boolean unifiedEnabled =
215+
configProvider.getBoolean(PROFILING_HEAP_ENABLED, isMemoryLeakProfilingSafe());
216+
if (!unifiedEnabled) {
217+
return false;
218+
}
219+
// JVMTI Allocation Sampler is required for ddprof live heap and is available since Java 11.
220+
// isJmethodIDSafe() alone is not sufficient — Java 8 is jmethodID-safe but lacks the sampler.
221+
boolean isSafe = JavaVirtualMachine.isJavaVersionAtLeast(11) && isJmethodIDSafe();
227222
boolean enableDdprofMemleak =
228223
getBoolean(
229224
configProvider,
230225
PROFILING_DATADOG_PROFILER_LIVEHEAP_ENABLED,
231-
PROFILING_DATADOG_PROFILER_LIVEHEAP_ENABLED_DEFAULT,
226+
isSafe,
232227
PROFILING_DATADOG_PROFILER_MEMLEAK_ENABLED);
233228
if (!isSafe && enableDdprofMemleak) {
234229
log.warn(
235-
"Memory leak profiling was enabled although it is not considered stable on this JVM version.");
230+
"Live heap profiling (ddprof) was enabled although it is not considered stable"
231+
+ " on this JVM version.");
232+
}
233+
if (!enableDdprofMemleak && !isOldObjectSampleAvailable()) {
234+
log.warn(
235+
"ddprof live heap profiling is disabled and JFR OldObjectSample is not available"
236+
+ " on this JVM. Live heap profiling will be inactive.");
236237
}
237238
return enableDdprofMemleak;
238239
}

dd-java-agent/agent-profiling/profiling-ddprof/src/test/java/com/datadog/profiling/ddprof/DatadogProfilerConfigTest.java

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
package com.datadog.profiling.ddprof;
22

3+
import static com.datadog.profiling.controller.ProfilingSupport.isOldObjectSampleAvailable;
34
import static org.junit.jupiter.api.Assertions.assertEquals;
5+
import static org.junit.jupiter.api.Assertions.assertFalse;
6+
import static org.junit.jupiter.api.Assertions.assertTrue;
47

8+
import datadog.environment.JavaVirtualMachine;
59
import datadog.trace.api.config.ProfilingConfig;
610
import datadog.trace.bootstrap.config.provider.ConfigProvider;
711
import java.util.Properties;
812
import java.util.stream.Stream;
913
import org.junit.jupiter.api.AfterEach;
1014
import org.junit.jupiter.api.BeforeEach;
15+
import org.junit.jupiter.api.Test;
1116
import org.junit.jupiter.params.ParameterizedTest;
1217
import org.junit.jupiter.params.provider.Arguments;
1318
import org.junit.jupiter.params.provider.MethodSource;
@@ -126,4 +131,70 @@ private static Stream<Arguments> hotspotStackwalkerTestCases() {
126131
Arguments.of("lbr", "lbr"),
127132
Arguments.of("no", "no"));
128133
}
134+
135+
@Test
136+
void isMemoryLeakProfilingSafeConsistentWithComponentChecks() {
137+
boolean expected = DatadogProfilerConfig.isJmethodIDSafe() || isOldObjectSampleAvailable();
138+
assertEquals(expected, DatadogProfilerConfig.isMemoryLeakProfilingSafe());
139+
}
140+
141+
@Test
142+
void unifiedFlagEnabledDdprofKeyDefaultReflectsSafety() {
143+
Properties props = new Properties();
144+
props.put(ProfilingConfig.PROFILING_HEAP_ENABLED, "true");
145+
ConfigProvider config = ConfigProvider.withPropertiesOverride(props);
146+
// ddprof live heap requires Java 11+ (JVMTI Allocation Sampler) AND jmethodID safety
147+
boolean expectedDefault =
148+
JavaVirtualMachine.isJavaVersionAtLeast(11) && DatadogProfilerConfig.isJmethodIDSafe();
149+
assertEquals(expectedDefault, DatadogProfilerConfig.isMemoryLeakProfilingEnabled(config));
150+
}
151+
152+
@Test
153+
void unifiedFlagDisabledOverridesDdprof() {
154+
Properties props = new Properties();
155+
props.put(ProfilingConfig.PROFILING_HEAP_ENABLED, "false");
156+
props.put(ProfilingConfig.PROFILING_DATADOG_PROFILER_LIVEHEAP_ENABLED, "true");
157+
ConfigProvider config = ConfigProvider.withPropertiesOverride(props);
158+
assertFalse(DatadogProfilerConfig.isMemoryLeakProfilingEnabled(config));
159+
}
160+
161+
@Test
162+
void unifiedFlagEnabledDdprofKeyDisabledReturnsFalse() {
163+
Properties props = new Properties();
164+
props.put(ProfilingConfig.PROFILING_HEAP_ENABLED, "true");
165+
props.put(ProfilingConfig.PROFILING_DATADOG_PROFILER_LIVEHEAP_ENABLED, "false");
166+
ConfigProvider config = ConfigProvider.withPropertiesOverride(props);
167+
assertFalse(DatadogProfilerConfig.isMemoryLeakProfilingEnabled(config));
168+
}
169+
170+
@Test
171+
void unifiedFlagEnabledDdprofKeyEnabledReturnsTrue() {
172+
Properties props = new Properties();
173+
props.put(ProfilingConfig.PROFILING_HEAP_ENABLED, "true");
174+
props.put(ProfilingConfig.PROFILING_DATADOG_PROFILER_LIVEHEAP_ENABLED, "true");
175+
ConfigProvider config = ConfigProvider.withPropertiesOverride(props);
176+
assertTrue(DatadogProfilerConfig.isMemoryLeakProfilingEnabled(config));
177+
}
178+
179+
@Test
180+
void oldMemleakAliasStillWorks() {
181+
Properties props = new Properties();
182+
props.put(ProfilingConfig.PROFILING_HEAP_ENABLED, "true");
183+
props.put(ProfilingConfig.PROFILING_DATADOG_PROFILER_MEMLEAK_ENABLED, "true");
184+
ConfigProvider config = ConfigProvider.withPropertiesOverride(props);
185+
assertTrue(DatadogProfilerConfig.isMemoryLeakProfilingEnabled(config));
186+
}
187+
188+
@Test
189+
void defaultBehaviorNoFlagsSetUsesAutoDetection() {
190+
Properties props = new Properties();
191+
ConfigProvider config = ConfigProvider.withPropertiesOverride(props);
192+
// With no flags set:
193+
// unified default = isMemoryLeakProfilingSafe()
194+
// ddprof default = Java 11+ && isJmethodIDSafe()
195+
// result = isMemoryLeakProfilingSafe() && (Java 11+ && isJmethodIDSafe())
196+
boolean expectedDefault =
197+
JavaVirtualMachine.isJavaVersionAtLeast(11) && DatadogProfilerConfig.isJmethodIDSafe();
198+
assertEquals(expectedDefault, DatadogProfilerConfig.isMemoryLeakProfilingEnabled(config));
199+
}
129200
}

0 commit comments

Comments
 (0)