google / google/guice

High level of lock contention with JIT bindings

Open
#1,190 0 comments 3 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.