Skip to content

Conversation

@jake-low
Copy link
Contributor

I've been investigating the rather high memory usage of the MapRoulette backend. I looked at the objects on the heap and noticed that there are a surprising number (9.2M when I checked) of instances of org.slf4j.helpers.BasicMarker.

$ jcmd $(pgrep -f maproulette) GC.class_histogram | head
  8:
  num     #instances         #bytes  class name (module)
  -------------------------------------------------------
  1:       9425051      803404472  [B (java.base@17.0.13)
  2:       9242472      295759104  java.util.concurrent.ConcurrentHashMap$Node (java.base@17.0.13)
  3:       9417056      226009344  java.lang.String (java.base@17.0.13)
  4:       9192783      220626792  java.util.concurrent.CopyOnWriteArrayList (java.base@17.0.13)
  5:       9192459      220619016  org.slf4j.helpers.BasicMarker
  6:       9238928      151017776  [Ljava.lang.Object; (java.base@17.0.13)
  7:       9214847      147437552  java.lang.Object (java.base@17.0.13)

These Marker objects are internally cached by the MarkerFactory. I think the expected pattern is to create a small, statically known set of Markers in your application; creating a distinct Marker per request means that memory usage grows without bound.

This PR removes the marker and instead just embeds the request UUID directly into the log message. If we want the UUID to also be automatically included in other log messages inside the request context (which the Marker approach does not accomplish), we should store the UUID in MDC, which uses a thread-local context that gets cleaned up when the request is over.

@sonarqubecloud
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants