jengebr commented on issue #3106:
URL: 
https://github.com/apache/logging-log4j2/issues/3106#issuecomment-2438548710

   ## Problem
   Data shows 2.24.x has nearly zero object allocation during the benchmark, 
but 2.25.0 has far more than that.  The allocation-heavy code in 2.25.x also 
comes with significant cpu load.
   
   **Caveat**: I'm not 100% certain I reproduced the specific issue reported.
   
   
   ## Data
   1. Async-profiler data shows that the overall hot path 
is`org.apache.logging.log4j.core.pattern.ThrowableExtendedStackTraceRenderer$ExtendedContext.lambda$createClassResourceInfoByName$0`.
  Put another way, 
`ThrowableExtendedStackTraceRenderer.createClassResourceInfoByName()`. 
   2. The benchmark (attached below) shows the old code allocates almost zero 
objects but the new code allocates rather more than that.
   3. The benchmark shows the old code is roughly 2x faster than the new, 
although that number may vary by system.
   
   ## Analysis
   Examination of `createClassResourceInfoByName` shows a very large amount of 
object allocation right at the beginning:
   
   ```
   final Map<String, ClassResourceInfo> classResourceInfoByName =
                StackLocatorUtil.getCurrentStackTrace().stream()
                                .collect(Collectors.toMap(
                                                Class::getName,
                                                clazz -> new 
ClassResourceInfo(clazz, true),
                                                (classResourceInfo1, 
classResourceInfo2) -> classResourceInfo1));
   final Set<Throwable> visitedThrowables = new HashSet<>();
   final Queue<Throwable> pendingThrowables = new 
ArrayDeque<>(Collections.singleton(rootThrowable));
   ```
   
   ... but what doesn't jump out is that there is a `new ClassResourceInfo()` 
for each item in the stack trace.  Diving into that constructor shows an 
indirect call to `String.format` - which is a very expensive and object-heavy 
convenience method. 
   
   ## Recommendations
   1. Do whatever it takes to eliminate `String.format` and any per-element 
object allocations.
   2. Reduce the allocations from the `HashSet` and `ArrayDeque`.
   
   ## Benchmark
   My benchmark is attached, and should be run with `-Xmx1g -Xms1g 
-XX:+UseParallelGC`.  It definitely reproduces *a* problem but I'm not certain 
it's exactly the one that was reported.... please let me know if I'm off.
   
   Config file: 
[log4j2.xml.txt](https://github.com/user-attachments/files/17525924/log4j2.xml.txt)
   Benchmark: 
[Log4jExceptionSpeedTest.java.txt](https://github.com/user-attachments/files/17525920/Log4jExceptionSpeedTest.java.txt)
   Support class for the benchmark: 
[TestRunner.java.txt](https://github.com/user-attachments/files/17525921/TestRunner.java.txt)
   


-- 
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: notifications-unsubscr...@logging.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to