You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by "Ralph Goers (JIRA)" <ji...@apache.org> on 2016/02/17 01:30:18 UTC

[jira] [Comment Edited] (LOG4J2-1270) Garbage-free steady-state logging

    [ https://issues.apache.org/jira/browse/LOG4J2-1270?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15149573#comment-15149573 ] 

Ralph Goers edited comment on LOG4J2-1270 at 2/17/16 12:29 AM:
---------------------------------------------------------------

Yes it is a big difference. But....

Classic uses ParameterizedMessage while NoGC uses NoGcMessage which is much simpler. NoGcMessage also relies on having p1 through p4 as individual parameters vs varargs array, Is that realistic? I have a suspicion that most of the gains seen are happening due to these differences.

NoGcLogger reuses the same NoGcMessage. At the very least it would have to be obtained from a ThreadLocal to be thread safe.
Likewise, NoGcLayout uses several objects, none of which are thread-safe.

One other thing I am concerned about is that NoGcMessage is formatting the message when it is created instead of when it is requested. I wouldn't want to see that in an actual implementation.





was (Author: ralph.goers@dslextreme.com):
Yes it is a big difference. But....

Classic uses ParameterizedMessage while NoGC uses NoGcMessage which is much simpler. NoGcMessage also relies on having p1 through p4 as individual parameters vs varargs array, Is that realistic?
NoGcLogger reuses the same NoGcMessage. At the very least it would have to be obtained from a ThreadLocal to be thread safe.
Likewise, NoGcLayout uses several objects, none of which are thread-safe.

One other thing I am concerned about is that NoGcMessage is formatting the message when it is created instead of when it is requested. I wouldn't want to see that in an actual implementation.


> Garbage-free steady-state logging
> ---------------------------------
>
>                 Key: LOG4J2-1270
>                 URL: https://issues.apache.org/jira/browse/LOG4J2-1270
>             Project: Log4j 2
>          Issue Type: Epic
>          Components: API, Appenders, Core, Layouts, Pattern Converters
>    Affects Versions: 2.5
>            Reporter: Remko Popma
>              Labels: gc
>
> In certain fields like finance, predictable latency is very important, and applications in this space tend to carefully manage their object allocation to avoid unpredictable GC pauses. As of 2.5, Log4j is not suitable to be included in such applications since it allocates new objects while running in its steady state.
> This ticket is to investigate the feasibility of modifying some key components in Log4j to provide a configuration that does not allocate new objects in its steady state. (Initialization or shutdown don't need to be allocation-free.)
> To clarify, I am not proposing to make all of Log4j allocation-free. My goal is to create an allocation-free execution path in Log4j with some reasonable subset of the Log4j functionality. For example, make logging garbage-free if all of these conditions are met: 
> * all loggers are AsyncLoggers
> * you only use the RandomAccessFileAppender
> * you only use a PatternLayout without any regular expression replacements, without lookups and with one of the pre-defined date formats. 
> Further restrictions may be necessary.
> AsyncLogger already has a ring buffer of pre-allocated LogEvents, so some of the work here is already done.
> Components that currently allocate objects in the critical path:
> # (API) Logger methods with vararg parameters
> # (API) All MessageFactory implementations
> # LoggerConfig.getProperties (if non-null) - wraps in Collections.unmodifiableMap
> # RingBufferLogEvent.mergePropertiesIntoContextMap (if LoggerConfig properties is non-null)
> # LoggerConfig.callAppenders (for-each loop over CopyOnWriteArraySet creates iterator)
> # Layout.toByteArray(LogEvent) - this API makes it difficult to avoid allocating a new byte[] array for each log event
> # AbstractStringLayout.toByteArray() - turns each LogEvent into a new String before turning the String into a byte[] array
> # DatePatternConverter - new CachedTime if event.millis differs from previous event
> # DatePatternConverter.CachedTime - new String caching the result
> # FixedDateFormat - new char[] array
> # (FastDateFormat - for each event: new GregorianCalendar, new StringBuilder, new char[], new String)
> # String.getBytes - creates initial byte array, CharBuffer, ByteBuffer, trimmed resulting byte array
> The Layout API and turning Strings into bytes are probably the most tricky areas. One advantage of restricting ourselves to async logging is that there is only a single background thread that does all the formatting and I/O, so we don't have to worry about concurrency issues when re-using buffers etc.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org