Pascal Davoust created WW-5121:
----------------------------------
Summary: High contention when injecting Scope.SINGLETON instances
Key: WW-5121
URL: https://issues.apache.org/jira/browse/WW-5121
Project: Struts 2
Issue Type: Bug
Components: Core
Affects Versions: 2.5.20
Reporter: Pascal Davoust
Attachments: image-2021-03-22-09-13-03-703.png
The container injection (DI) mechanism shows high contention when injecting
{{Scope.SINGLETON}} instances under high stress load in an enterprise
application using Struts 2.5.20.
The symptom is that UI response times vary from a few dozens of milliseconds up
to a full second without any obvious reason.
Profiling the app while under load stress using
[https://github.com/jvm-profiling-tools/async-profiler] (using the {{lock}}
mode and {{--reverse}} option to aggregate on the various contention code
locations) shows the following picture:
!image-2021-03-22-09-13-03-703.png!
Analyzing the code path shows the highly contended code:
{code:java}
SINGLETON {
@Override
<T> InternalFactory<? extends T> scopeFactory(Class<T> type, String
name, final InternalFactory<? extends T> factory) {
return new InternalFactory<T>() {
T instance;
public T create(InternalContext context) {
synchronized (context.getContainer()) {
if (instance == null) {
instance =
InitializableFactory.wrapIfNeeded(factory).create(context);
}
return instance;
}
}
...
},{code}
The fully {{synchronised}} section for accessing the singleton instance is the
core issue here.
Using the double-null check-on-volatile pattern (which I dislike but is
reliable since Java 1.5 with the {{volatile}} keyword) entirely removes the
contention issue and response times become much more stable.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)