High level of lock contention with JIT bindings
- Dominant language
- Java
- Stars
- 12.7k
- Forks
- 1.7k
- Avg merge
- 11m
- Merged PRs (30d)
- 2
Description
Guice currently accesses JIT bindings from a synchronized block. This can become a problem in large server instances, if injection happens frequently (as a common example, per request). We have seen tens of threads constantly being blocked in a highly loaded server.
A jmh project here to reproduce the issue: https://github.com/asaarilahti/guice-jit-bindings-perf-test
In most cases there's a simple workaround to use explicit bindings. Still, would be preferable if both types of bindings could have similar performance.
Fixing the issue does not look trivial, at least because bindings are added to jitBindings map early to support circular references. So simply switching to ConcurrentMap won't work.
Potential solutions:
1. Use ReadWriteLock - not optimal, fast path likely slower than with current solution
1. StampedLock might be a good fit but cannot be used as Guice supports Java 7
1. Use ConcurrentMap for jitBindings and have a volatile initialized flag in BindingImpl and acquire lock in case a Binding is not initialized
1. Use ConcurrentMap for jitBindings but use a distinct map for uninitialized bindings
3 and 4 likely have a lot of subtleties, so needs some more thought.
Contributor guide
Assessment
This issue has not been assessed yet.