Myllyenko opened a new pull request, #4322:
URL: https://github.com/apache/logging-log4j2/pull/4322

   `InstantPatternThreadLocalCachedFormatter` keyed its per-thread cache on a 
`Long`: the epoch instant was extracted through a `Function<Instant, Long>` and 
stored, boxed, into an `Object[]` held in a `ThreadLocal`. Both extractors, 
`Instant::getEpochMillisecond` and `Instant::getEpochSecond`, return a 
primitive, and epoch values are far outside the `Long` cache.
   
   The extractor's box turns out to be scalar-replaced on a cache hit, since it 
is unboxed straight into a local and never escapes. The box stored into the 
`Object[]` does escape, so every cache miss allocated. A miss happens once per 
distinct instant per thread, which for any thread logging at under a thousand 
events per second is every single event.
   
   Replace the extractor with a `ToLongFunction<Instant>` and the `Object[]` 
with a small holder carrying a primitive `long` field next to the buffer. 
`StringBuilderEncoder` documents a preference for keeping only JDK types in 
thread locals, to avoid pinning a class loader in a web container, but that 
does not apply here: this wrapper is only installed when 
`Constants.ENABLE_THREADLOCALS` is set, and that flag is off for web 
applications precisely to disable the thread locals which could leak.
   
   Measured with the JMH benchmark added here, 1000 instants per operation:
   
                           before                 after
       cacheMiss   24000.152 B/op, 153 GCs    0.141 B/op, no GC
       cacheMiss    21744 +- 2404 ns/op       20274 +- 406 ns/op
       cacheHit         0.038 B/op              0.040 B/op
       cacheHit      5410 +- 70 ns/op          5696 +- 699 ns/op
   
   Also close a cache-poisoning window while here: the cached epoch instant is 
now cleared before the buffer is rewritten and restored only once formatting 
succeeds, so a throwing formatter can no longer leave a later call reading a 
half-written buffer. Note that merely moving the assignment after the 
formatting does not fix this; it only changes which instant triggers it.
   
   **INSERT HERE** a clear and concise description of what the pull request is 
for along with a reference to the associated issue IDs, if they exist.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to