-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Non-cachable deserializers are still created in a single-threaded way #1394
Comments
Interesting. Yes, I agree that avoiding synchronization for non-cachable instances would make sense. |
Looking at the code, I am not overly optimistic about possibilities for rearranging. The problem is that cachability is only known at a rather late point (after locating/constructing said deserializer) and even without caching it is necessary to resolve recursive refefences (via |
During load tests, there is significant lock contention in Jackson when using the FuzzyEnumModule. For each serialized enum type, there is a synchronized block that attempts to create a serializer in the cache and ultimately since the PermissiveEnumDeserializer isn't marked as cacheable, the underlying deserializer is recreated each time. Update the PermissiveEnumDeserializer to be cacheable (similar to EnumDeserializer from Jackson) to remove significant overhead during deserialization. Refs FasterXML/jackson-databind#1394
@cowtowncoder I faced the same Performance issues with synchronized block when running many threads; I think we should replace synchronized block with ThreadLocal; |
@sandszhouSZ most of the time the real problem is not this blocking, but rather question of why are deserializers not being reused (caching is just one mechanism): synchronization is only needed when creating deserializer for the first time. I am not sure how |
Depending on how your code is structured, use of My concern with ThreadLocal approach really is that it seems to have a good chance of leading to unintentional memory retention (every thread will have |
During load tests, there is significant lock contention in Jackson when using the FuzzyEnumModule. For each serialized enum type, there is a synchronized block that attempts to create a serializer in the cache and ultimately since the PermissiveEnumDeserializer isn't marked as cacheable, the underlying deserializer is recreated each time. Update the PermissiveEnumDeserializer to be cacheable (similar to EnumDeserializer from Jackson) to remove significant overhead during deserialization. Refs FasterXML/jackson-databind#1394
This is related to issues #735 and #604.
Deserializers are created and cached in
com.fasterxml.jackson.databind.deser.DeserializerCache#_createAndCacheValueDeserializer
within asynchronized
block. The comment in that file explains that "Only one thread to construct deserializers at any given point in time; limitations necessary to ensure that only completely initialized ones are visible and used". In case the deserializer is not cachable, we do not need to lock the cache with thesynchronized
block; we can just create a new deserializer and return it. However, the code still creates a lock and calls_createAndCache2
, which then checks whether the deserializer is cachable.So, for a deserializer that is not cachable, the lock is created even though cache is not being updated, so no locking is needed.
The result of this is a multithreading lock contention for non-cachable deserializer. In scenarios where many threads are deserializing at once, this contention leads to severe degradation of performance.
This problem has been mitigated as of version 2.8.x by enabling more deserializers to be cached. However, if serializers are not cached (because they are custom serializers with complicated behavior), performance degradation due to unnecessary locking will still occur.
Perhaps it is possible to rearrange the logic in
DeserializerCache#_createAndCache2
andDeserializerCache#_createAndCacheValueDeserializer
so that non-cachable deserializers are created without a global lock.The text was updated successfully, but these errors were encountered: