Skip to content

Commit 31042f1

Browse files
An option to select TLAB based AllocTracer engine with JDK 11+ (async-profiler#1671)
1 parent a3c6d92 commit 31042f1

File tree

7 files changed

+35
-5
lines changed

7 files changed

+35
-5
lines changed

docs/ProfilerOptions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ The below options are `action`s for async-profiler and common for both `asprof`
3232
| `-e --event EVENT` | `event=EVENT` | The profiling event: `cpu`, `alloc`, `nativemem`, `lock`, `cache-misses` etc. Use `list` to see the complete list of available events.<br>Please refer to [Profiling Modes](ProfilingModes.md) for additional information. |
3333
| `-i --interval N` | `interval=N` | Interval has different meaning depending on the event. For CPU profiling, it's CPU time in nanoseconds. In wall clock mode, it's wall clock time. For Java method profiling or native function profiling, it's number of calls. For PMU profiling, it's number of events. Time intervals may be followed by `s` for seconds, `ms` for milliseconds, `us` for microseconds or `ns` for nanoseconds.<br>Example: `asprof -e cpu -i 5ms 8983` |
3434
| `--alloc N` | `alloc=N` | Allocation profiling interval in bytes or in other units, if N is followed by `k` (kilobytes), `m` (megabytes), or `g` (gigabytes). |
35+
| `--tlab` | `tlab` | Use TLAB events for allocation profiling |
3536
| `--live` | `live` | Retain allocation samples with live objects only (object that have not been collected by the end of profiling session). Useful for finding Java heap memory leaks. |
3637
| `--nativemem N` | `nativemem=N` | Native memory allocation profiling. N, if specified is the interval in bytes or in other units, if N is followed by `k` (kilobytes), `m` (megabytes), or `g` (gigabytes). Default N is 0. |
3738
| `--nofree` | `nofree` | Will not record free calls in native memory allocation profiling. This is relevant when tracking memory leaks is not important and there are lots of free calls. |

src/arguments.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ const size_t EXTRA_BUF_SIZE = 512;
5050
// version - display the agent version
5151
// event=EVENT - which event to trace (cpu, wall, cache-misses, etc.)
5252
// alloc[=BYTES] - profile allocations with BYTES interval
53+
// tlab - use TLAB events for allocation profiling
5354
// live - build allocation profile from live objects only
5455
// nativemem[=BYTES] - profile native allocations with BYTES interval
5556
// nofree - do not collect free calls in native allocation profiling
@@ -246,6 +247,9 @@ Error Arguments::parse(const char* args) {
246247
CASE("alloc")
247248
_alloc = value == NULL ? 0 : parseUnits(value, BYTES);
248249

250+
CASE("tlab")
251+
_tlab = true;
252+
249253
CASE("nativemem")
250254
_nativemem = value == NULL ? 0 : parseUnits(value, BYTES);
251255

src/arguments.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ class Arguments {
200200
bool _threads;
201201
bool _sched;
202202
bool _record_cpu;
203+
bool _tlab;
203204
bool _live;
204205
bool _nofree;
205206
bool _nobatch;
@@ -261,6 +262,7 @@ class Arguments {
261262
_threads(false),
262263
_sched(false),
263264
_record_cpu(false),
265+
_tlab(false),
264266
_live(false),
265267
_nofree(false),
266268
_nobatch(false),

src/main/main.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ static const char USAGE_STRING[] =
6969
"\n"
7070
" --loop time run profiler in a loop\n"
7171
" --alloc bytes allocation profiling interval in bytes\n"
72+
" --tlab use TLAB events for allocation profiling\n"
7273
" --live build allocation profile from live objects only\n"
7374
" --nativemem bytes native allocation profiling interval in bytes\n"
7475
" --nofree do not collect free calls in native allocation profiling\n"
@@ -501,7 +502,8 @@ int main(int argc, const char** argv) {
501502
format << "," << (arg.str() + 2) << "=" << args.next();
502503

503504
} else if (arg == "--reverse" || arg == "--inverted" || arg == "--samples" || arg == "--total" ||
504-
arg == "--sched" || arg == "--live" || arg == "--nofree" || arg == "--record-cpu") {
505+
arg == "--sched" || arg == "--live" || arg == "--nofree" || arg == "--record-cpu" ||
506+
arg == "--tlab") {
505507
format << "," << (arg.str() + 2);
506508

507509
} else if (arg == "--alloc" || arg == "--nativemem" || arg == "--nativelock" || arg == "--lock" ||

src/profiler.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -991,8 +991,8 @@ Engine* Profiler::selectEngine(Arguments& args) {
991991
}
992992
}
993993

994-
Engine* Profiler::selectAllocEngine(long alloc_interval, bool live) {
995-
if (VM::addSampleObjectsCapability()) {
994+
Engine* Profiler::selectAllocEngine(bool tlab) {
995+
if (!tlab && VM::addSampleObjectsCapability()) {
996996
return &object_sampler;
997997
} else if (VM::isOpenJ9()) {
998998
return &j9_object_sampler;
@@ -1204,7 +1204,7 @@ Error Profiler::start(Arguments& args, bool reset) {
12041204
}
12051205

12061206
if (_event_mask & EM_ALLOC) {
1207-
_alloc_engine = selectAllocEngine(args._alloc, args._live);
1207+
_alloc_engine = selectAllocEngine(args._tlab);
12081208
error = _alloc_engine->start(args);
12091209
if (error) {
12101210
goto error2;

src/profiler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ class Profiler {
123123
void updateNativeThreadNames();
124124
void mangle(const char* name, char* buf, size_t size);
125125
Engine* selectEngine(Arguments& args);
126-
Engine* selectAllocEngine(long alloc_interval, bool live);
126+
Engine* selectAllocEngine(bool tlab);
127127
Engine* activeEngine();
128128
Error checkJvmCapabilities();
129129

test/test/alloc/AllocTests.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
package test.alloc;
77

8+
import jdk.jfr.consumer.RecordedEvent;
9+
import jdk.jfr.consumer.RecordingFile;
810
import one.jfr.JfrReader;
911
import one.jfr.StackTrace;
1012
import one.jfr.event.AllocationSample;
@@ -61,6 +63,25 @@ public void humongous(TestProcess p) throws Exception {
6163
assert out.contains("G1CollectedHeap::humongous_obj_allocate");
6264
}
6365

66+
@Test(mainClass = MapReaderOpt.class)
67+
public void tlabAllocSampler(TestProcess p) throws Exception {
68+
p.profile("-e alloc --tlab -d 3 -f %profile.jfr");
69+
boolean tlabEvent = false;
70+
71+
try (RecordingFile recordingFile = new RecordingFile(p.getFile("%profile").toPath())) {
72+
while (recordingFile.hasMoreEvents()) {
73+
RecordedEvent event = recordingFile.readEvent();
74+
String eventName = event.getEventType().getName();
75+
if (eventName != null && eventName.equals("jdk.ObjectAllocationOutsideTLAB")) {
76+
tlabEvent = true;
77+
break;
78+
}
79+
}
80+
}
81+
82+
assert tlabEvent : "No jdk.ObjectAllocationOutsideTLAB event was found";
83+
}
84+
6485
@Test(mainClass = MapReaderOpt.class, jvmVer = {11, Integer.MAX_VALUE})
6586
public void objectSamplerWtihDifferentAsprofs(TestProcess p) throws Exception {
6687
Output out = p.profile("-e alloc -d 3 -o collapsed");

0 commit comments

Comments
 (0)