Fixed
Status Update
Comments
ch...@google.com <ch...@google.com> #2
Thanks for the bug report. Adding or removing listeners while metrics are already being delivered (on a different thread) can indeed cause this problem. Should have a fix soon (spoiler: all access of the delegates list should synchronize on a common object).
ch...@google.com <ch...@google.com> #3
ok, traced the problem and have a minor fix out for review (along the way finding and fixing a related bug where metrics listeners pre-24 would never be removed...)
The root cause was that the metrics were being served to listeners ("delegates") on whatever thread the metrics came in on internally (the UI thread for pre-24, and the FrameMetrics thread on 24+). Meanwhile, delegates could be added (via JankStats.enable or by creating a new JankStats instance) on any arbitrary thread, causing potential concurrency issues as the list was being modified while it was potentially being used by a different thread to serve results.
The fix is to synchronize on an object that always exists when the delegates do (the DecorView on pre-24 and the Window on 24+). Fix out for review now.
The root cause was that the metrics were being served to listeners ("delegates") on whatever thread the metrics came in on internally (the UI thread for pre-24, and the FrameMetrics thread on 24+). Meanwhile, delegates could be added (via JankStats.enable or by creating a new JankStats instance) on any arbitrary thread, causing potential concurrency issues as the list was being modified while it was potentially being used by a different thread to serve results.
The fix is to synchronize on an object that always exists when the delegates do (the DecorView on pre-24 and the Window on 24+). Fix out for review now.
ap...@google.com <ap...@google.com> #4
Project: platform/frameworks/support
Branch: androidx-main
commit ad8374548413e97f36573731aaa6d18f7a4abdea
Author: Chet Haase <chet@google.com>
Date: Mon May 09 17:51:36 2022
Allow for concurrent modification of delegators list
JankStats allows multiple JankStats instances to be active on the same
window, each with their own listener receiving metrics which are delegated
from a single listener inside of JankStats. But the thread issuing metrics
(the UI thread pre-24, or the FrameMetrics thread in 24+) may not be the
same thread in which JankStats are created, which add to the list of
delegates, causing potential concurrent modifications as delegates are
added or removed from the same list that is being iterated through
on a different thread to send metrics.
The fix is to synchronize around a common object which the delegates use.
For pre-24, we use the DecorView, which is where the tag is set to stash
the root listener which delegates to the list of delegates. On 24+ we
use the Window owning that DecorView (because it is more accessible in the
places it is needed). Note that we only need to synchronize at the root of
all code paths accessing the delegates list, which is during processing of
a frame callback (OnPreDrawListener pre-24 or FrameMetricsListener 24+),
as well as setupFrameTimer(), which the calls methods to add or remove
delegates.
Along the way, fixed a bug in JankStatsApi16Impl which prevented delegates
from being removed at all (now also tested in
JankStatsTest#testMultipleListeners())
Bug: 230388846
Test: Added to JankStatsTest#testMultipleListeners, ran on API 17, 24, and 32
Change-Id: I2827f94eeee646e8d2c439c16997a2950fe80a10
M metrics/metrics-performance/src/main/java/androidx/metrics/performance/JankStatsApi24Impl.kt
M metrics/metrics-performance/src/main/java/androidx/metrics/performance/JankStatsApi16Impl.kt
M metrics/metrics-performance/src/androidTest/java/androidx/metrics/performance/test/JankStatsTest.kt
https://android-review.googlesource.com/2092714
Branch: androidx-main
commit ad8374548413e97f36573731aaa6d18f7a4abdea
Author: Chet Haase <chet@google.com>
Date: Mon May 09 17:51:36 2022
Allow for concurrent modification of delegators list
JankStats allows multiple JankStats instances to be active on the same
window, each with their own listener receiving metrics which are delegated
from a single listener inside of JankStats. But the thread issuing metrics
(the UI thread pre-24, or the FrameMetrics thread in 24+) may not be the
same thread in which JankStats are created, which add to the list of
delegates, causing potential concurrent modifications as delegates are
added or removed from the same list that is being iterated through
on a different thread to send metrics.
The fix is to synchronize around a common object which the delegates use.
For pre-24, we use the DecorView, which is where the tag is set to stash
the root listener which delegates to the list of delegates. On 24+ we
use the Window owning that DecorView (because it is more accessible in the
places it is needed). Note that we only need to synchronize at the root of
all code paths accessing the delegates list, which is during processing of
a frame callback (OnPreDrawListener pre-24 or FrameMetricsListener 24+),
as well as setupFrameTimer(), which the calls methods to add or remove
delegates.
Along the way, fixed a bug in JankStatsApi16Impl which prevented delegates
from being removed at all (now also tested in
JankStatsTest#testMultipleListeners())
Bug: 230388846
Test: Added to JankStatsTest#testMultipleListeners, ran on API 17, 24, and 32
Change-Id: I2827f94eeee646e8d2c439c16997a2950fe80a10
M metrics/metrics-performance/src/main/java/androidx/metrics/performance/JankStatsApi24Impl.kt
M metrics/metrics-performance/src/main/java/androidx/metrics/performance/JankStatsApi16Impl.kt
M metrics/metrics-performance/src/androidTest/java/androidx/metrics/performance/test/JankStatsTest.kt
ch...@google.com <ch...@google.com>
aa...@gmail.com <aa...@gmail.com> #5
When new version of the library will be released with this fix?
I am getting impacted with this exception, is there any workaround for now which I can use till the time new version with fix is released?
I am getting impacted with this exception, is there any workaround for now which I can use till the time new version with fix is released?
zg...@gmail.com <zg...@gmail.com> #6
I used your latest modified code. The previous errors have been reduced, but the problem of concurrentmodificationexception still occurs
Description
`androidx.metrics` version used: 1.0.0-alpha01
Devices/Android versions reproduced on: multiple android versions 11, 10, 12, 9
When you encountered this bug:
• Issue is reported on production. App is crashing with ConcurrentModificationException. We are initialising JankStat on
every fragment to measure the jank frames for that fragment.
If this is a bug in the library, we would appreciate it if you could attach:
• Attaching screenshot of bugsnag trace.