You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In this code, the number of calls to testSmallAlloc and testLargeAlloc is different, but their total memory allocations in bytes are close, which can also be proven from the actual running logs.
If use async-profiler to profiling allocation with --total mode.
openjdk version "1.8.0_372"
OpenJDK Runtime Environment (build 1.8.0_372-b07)
OpenJDK 64-Bit Server VM (build 25.372-b07, mixed mode)
java -Xint AllocTest
/root/async-profiler-fork/build/bin/asprof --alloc 5m -f static/profile.html --total -d 10 jps
We can see testLargeAlloc is 21% while testSmallAlloc is 78%. This is different from our expectation of 50/50.
I thought this might be related to TLAB, so I adjusted TLAB, and the result was still not right, but this time the ratio of the two was reversed.
I modified the code slightly and it looks much better this time.
Then I removed the TLAB related flags and verified again, and found that the problem still exists, not half and half as expected. However, the proportion of testLargeAlloc is slightly larger, reaching 25%, which may be related to my changes.
java -Xint AllocTest
I used Java Flight Recorder to analyze it again, and found that it looked similar to the results of async-profiler. The ratio of testSmallAlloc reached 70%. The root cause of this deviation may be related to TLAB, because both async-profiler and JFR on Java 8 are based on send_allocation_in_new_tlab_event and send_allocation_outside_tlab_event, so both are affected.
(This is a flame graph generated by one of our internal tools for parsing JFR)
I verified it again with Java 17, because Java 17 uses JVMTI, and the JVMTI added some randomness to internal, so the expected results will be more accurate.
But because the issue #873,the result is not correct.
So I ran it with the modified version, and it looked much more normal, almost as expected.
To sum up, I feel there are two problems
On Java 8, the send_allocation_in_new_tlab_event and send_allocation_outside_tlab_event we currently rely on may, in some cases, may lead to a proportional deviation in the flame graph. I have not thought of any good way to avoid this.
In AllocTracer::trapHandler, is it a better choice to use _allocated_bytes + total_size - (_allocated_bytes + total_size) % _interval as total_size parameter?
The text was updated successfully, but these errors were encountered:
I'd say the issue here is the expectation :)
TLAB-based allocation events in JDK 8 provide neither an estimate of allocation count nor amount of memory allocated. Therefore, no conclusion can be made about the proportion of allocated bytes.
JMC calls this metric an "allocation pressure", which roughly measures the impact on GC.
I have no plans to change anything in this regard for JDK 8.
Thank you for your reply.
Through this issue, I have a better understanding of TLAB-based allocation profiling, and I will use it more carefully in the future.
hi Andrei
The same reproducer as #873。
In this code, the number of calls to
testSmallAlloc
andtestLargeAlloc
is different, but their total memory allocations in bytes are close, which can also be proven from the actual running logs.If use
async-profiler
to profilingallocation
with--total
mode.openjdk version "1.8.0_372" OpenJDK Runtime Environment (build 1.8.0_372-b07) OpenJDK 64-Bit Server VM (build 25.372-b07, mixed mode) java -Xint AllocTest /root/async-profiler-fork/build/bin/asprof --alloc 5m -f static/profile.html --total -d 10 jps
We can see
testLargeAlloc
is 21% whiletestSmallAlloc
is 78%. This is different from our expectation of 50/50.I thought this might be related to
TLAB
, so I adjustedTLAB
, and the result was still not right, but this time the ratio of the two was reversed.I feel that the use of
total_size
instead of_interval
inAllocTracer::trapHandler
may be the reason.async-profiler/src/allocTracer.cpp
Line 62 in 915b090
I modified the code slightly and it looks much better this time.
Then I removed the
TLAB
relatedflags
and verified again, and found that the problem still exists, not half and half as expected. However, the proportion oftestLargeAlloc
is slightly larger, reaching 25%, which may be related to my changes.I used
Java Flight Recorder
to analyze it again, and found that it looked similar to the results ofasync-profiler
. The ratio oftestSmallAlloc
reached 70%. The root cause of this deviation may be related toTLAB
, because both async-profiler and JFR on Java 8 are based onsend_allocation_in_new_tlab_event
andsend_allocation_outside_tlab_event
, so both are affected.(This is a flame graph generated by one of our internal tools for parsing JFR)
I verified it again with Java 17, because Java 17 uses
JVMTI
, and theJVMTI
added some randomness tointernal
, so the expected results will be more accurate.But because the issue #873,the result is not correct.
So I ran it with the modified version, and it looked much more normal, almost as expected.
To sum up, I feel there are two problems
send_allocation_in_new_tlab_event
andsend_allocation_outside_tlab_event
we currently rely on may, in some cases, may lead to a proportional deviation in the flame graph. I have not thought of any good way to avoid this.AllocTracer::trapHandler
, is it a better choice to use_allocated_bytes + total_size - (_allocated_bytes + total_size) % _interval
as total_size parameter?The text was updated successfully, but these errors were encountered: