[
https://issues.apache.org/jira/browse/LOG4J2-1349?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15350000#comment-15350000
]
Remko Popma commented on LOG4J2-1349:
-------------------------------------
About the worse performance: I think I did not present that well. True,
garbage-free is not _always_ better, but by a small margin and in rare cases.
Perhaps I over-emphasized them in the performance docs. Note that the
garbage-free initiative has made Log4j 2.6 faster than 2.5 in all tests.
Overall, the feedback on Log4j going gc-free has been overwhelmingly positive,
so I don't think we are on the wrong track.
On the other hand, I understand that you want to keep complexity within reason.
About my proposal, the problem here is that context key-value data can only be
accessed as a java.util.Map. For the stack, ThreadContext exposes the
ContextStack interface, but the equivalent ThreadContextMap SPI interface
cannot be accessed from ThreadContext.
I want to add a method {{getThreadContextMap()}} to ThreadContext, so that the
context data injector in LOG4J2-1010 can look like this:
{code}
public class DefaultContextDataInjector implements ContextDataInjector {
@Override
public void injectContextData(final List<Property> properties, final
LogEvent event) {
copyProperties(properties, event.getContextData());
final ThreadContextMap contextMap =
ThreadContext.getThreadContextMap(); // <-- the new method
copyThreadContextMap(contextMap, event.getContextData());
}
private void copyThreadContextMap(final ThreadContextMap contextMap,
final ContextData<Object, Object> contextData) {
if (contextMap instanceof IndexedMap) { // garbage-free
IndexedMap<Object, Object> indexedMap = (IndexedMap<Object,
Object>) contextMap;
for (int i = 0; i < indexedMap.size(); i++) {
contextData.put(indexedMap.getKeyAt(i),
indexedMap.getValueAt(i));
}
} else { // classic
final Map<String, String> map = contextMap.getImmutableMapOrNull();
if (map != null) {
for (Map.Entry<String, String> entry : map.entrySet()) {
contextData.put(entry.getKey(), entry.getValue());
}
}
}
}
private void copyProperties(final List<Property> properties, final
ContextData<Object, Object> contextData) {
if (properties != null) {
for (int i = 0; i < properties.size(); i++) {
final Property prop = properties.get(i);
contextData.put(prop.getName(), prop.getValue());
}
}
}
}
interface IndexedMap<K, V> {
int size();
K getKeyAt(i);
V getValueAt(i);
}
{code}
> Garbage-free ThreadContext map
> ------------------------------
>
> Key: LOG4J2-1349
> URL: https://issues.apache.org/jira/browse/LOG4J2-1349
> Project: Log4j 2
> Issue Type: Improvement
> Components: API
> Affects Versions: 2.5
> Reporter: Remko Popma
> Assignee: Remko Popma
> Fix For: 2.7
>
>
> The current ThreadContext map and stack implementations allocate temporary
> objects. This ticket is to investigate and track the work for alternative
> implementations that are garbage-free.
> Both DefaultThreadContextMap and DefaultThreadContextStack are copy-on-write
> data structures: each modification replaces the ThreadLocal object with a
> modified copy. The advantage of this approach is that there is no need to
> make a copy for each LogEvent.
> Also, DefaultThreadContextMap uses a JDK map, the JDK collections tend to
> allocate a lot of temporary objects.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]