6

I am using JProfiler to inspect a Java microservice while I simulate concurrent users with JMeter. With JProfiler I can see: Overview Thread History Monitor Usage Monitor History Navigating to the method find(), I realized the method has synchronized keyword method

In my opinion this method causes the problem with blocked threads. But why is it used? May I disabled this cache mechanism from microservice? The microservice is written in Java and it uses Spring, Spring Boot.

Thank you

I added screenshot from the same JProfiler snapshot for Monitor History to show the time spent in the ResolvedTypeCache class. Sometimes the time is less but sometimes is huge. History Monitor Update

Adrian
  • 395
  • 3
  • 13
  • 3
    This deserves a github issue on the jackson project - this has nothing to do with spring-boot. – Brian Clozel Mar 02 '18 at 08:44
  • @BrianClozel I never did that. Can you provide me a link, please? – Adrian Mar 02 '18 at 11:45
  • There you go https://github.com/FasterXML/java-classmate/issues – Kayaman Mar 02 '18 at 13:43
  • Looks like Hibernate validator really should be one caching resolved types, as it should not have to do this for every read call? Although Classmate has simple cache it is not designed for heavy lock contestion; it is based on JDK `LinkedHashMap` and has to be synchronized (as it is now) for each get/put call. – StaxMan Mar 27 '18 at 00:03

2 Answers2

2

Why is LRU used? Presumably because there's something worth caching.

Why is it synchronized? Because the LinkedHashMap that's being used as a cache here is not thread-safe. It does provide the idiomatic LRU mechanism though.

It could be replaced with a ConcurrentMap to mitigate the synchronization, but then you'd have a constantly growing non-LRU cache and that's not at all the same thing.

Now there's not much you can do about it. The best idea might be to contact the devs and let them know about this. All in all the library may just not be suitable for the amount of traffic your putting through it, or you may be simulating the kind of traffic that would exhibit pathological behaviour, or you may overestimate the impact of this (not offense, I'm just very Mulderesque about SO posts, i.e. "trust no1").

Finally, uncontested synchronization is cheap so if there's a possibility to divide traffic to multiple instances of the cache it may affect performance in some way (not necessarily positive). I don't know about the architecture of the library though, so it may be completely impossible.

Kayaman
  • 72,141
  • 5
  • 83
  • 121
1

Your conclusion seems very wrong to me, especially when you imply that this is either bad or that there is a potential dead-lock.

The fact that there are synchronized methods inside that class is no indication of dead-locks. It's just the fact that there are multiple threads that wait on a single Lock - this is what synchronized does after all. Also look at those times, those look like micro-seconds, and the most that threads stay there is 4000 which is about 4ms - not that much.

Since this is an internal library, there is not much you can do about it, may be suggest them to implement a ConcurrentHashMap that will improve performance or better make a patch yourself.

Eugene
  • 117,005
  • 15
  • 201
  • 306
  • I did another screenshot from the same JProfiler snapshot. In the image can be seen better the time spent . – Adrian Mar 02 '18 at 10:46
  • @Adrian it does not matter - of course multiple threads will stay blocked until they get a lock – Eugene Mar 02 '18 at 10:49
  • In my opinion if I get rid of this problem, the response time will be better. I have this problem when I simulate 25 concurrent users, so it will be better If I get rid. What do you think? – Adrian Mar 02 '18 at 10:54
  • @Adrian and how exactly do you plan "to get rid" of it? – Eugene Mar 02 '18 at 10:55
  • I can try to use another JSON library. I addressed this question to see if someone else experienced this issue – Adrian Mar 02 '18 at 10:58
  • 2
    @Adrian of course that is an option, but will that give you any benefits? refactor/probably face some other potential issues... it's not as simple as it sounds. The correct thing would be to get the original source, create a patch, test it locally, submit a patch to the original provider of the lib... this is what we sometimes do when we face these issues, you are relying on open-source software, might as well give something back once in a while – Eugene Mar 02 '18 at 11:00
  • Note that it is not actually JSON library that is caching things. Classmate is (generic) type resolution library, and called by, it seems, Hibernate validator (jsr-303 implementation), most likely called by framework (sprint boot?) to validate payload. So change would have to address that. However I would not necessarily do that without being sure this is actual performance problem -- contention itself does not necessarily mean that. – StaxMan Mar 27 '18 at 00:05