Repository: logging-log4j2
Updated Branches:
  refs/heads/master 266d12b37 -> 83023b59f


LOG4J2-1297 garbagefree.xml update


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/83023b59
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/83023b59
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/83023b59

Branch: refs/heads/master
Commit: 83023b59fd79403cd57ebfa790555ab7e0573844
Parents: 266d12b
Author: rpopma <[email protected]>
Authored: Sun Apr 3 15:10:08 2016 +0900
Committer: rpopma <[email protected]>
Committed: Sun Apr 3 15:10:08 2016 +0900

----------------------------------------------------------------------
 src/site/xdoc/manual/garbagefree.xml | 138 ++++++++++++++----------------
 1 file changed, 62 insertions(+), 76 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/83023b59/src/site/xdoc/manual/garbagefree.xml
----------------------------------------------------------------------
diff --git a/src/site/xdoc/manual/garbagefree.xml 
b/src/site/xdoc/manual/garbagefree.xml
index 5541e23..fef6005 100644
--- a/src/site/xdoc/manual/garbagefree.xml
+++ b/src/site/xdoc/manual/garbagefree.xml
@@ -85,32 +85,43 @@
           <p>
             In Log4j 2.6, garbage-free logging is enabled by default, except 
for web applications.
             Log4j will disable garbage-free logging if it detects that it is 
used in a web application
-            (either because the <tt>javax.servlet.Servlet</tt>
-            is in the classpath or because the "log4j2.is.webapp" system 
property is set to true).
+            (either when the <tt>javax.servlet.Servlet</tt>
+            is in the classpath or when the <tt>log4j2.is.webapp</tt> system 
property is set to "true").
             This is because garbage-free logging uses a number of ThreadLocal 
fields, which can cause
             memory leaks when the thread pools of web application containers 
hold references
             to these fields even after the web application is undeployed.
           </p>
           <p>
             It is possible to manually disable garbage-free logging by setting 
system property
-            "log4j2.enable.threadlocals" to false before Log4j is initialized.
-            (The above properties can also be specified by creating a file 
named
-            <tt>log4j2.component.properties</tt> and including it in the 
classpath of the application.
+            <tt>log4j2.enable.threadlocals</tt> to "false" before Log4j is 
initialized.
           </p>
+          <p>
+            The above properties can also be specified by creating a file named
+            <tt>log4j2.component.properties</tt> and including this file in 
the classpath of the application.
+          </p>
+          <table><tr><td><b>Caution:</b> as of version 2.6, a Log4j 
configuration containing a <tt>&lt;Properties&gt;</tt> section
+            will result in temporary objects being created during steady-state 
logging.
+          </td></tr></table>
         </subsubsection>
         <a name="Appenders" />
         <subsubsection name="Appenders">
           <h4>Appenders</h4>
           <p>
-            Supported appenders: Console, File, RollingFile, RandomAccessFile, 
RollingRandomAccessFile,
+            The following <a href="appenders.html">appenders</a> are 
garbage-free:
+            Console, File, RollingFile, RandomAccessFile, 
RollingRandomAccessFile,
             MemoryMappedFile, and Socket.
           </p>
+          <p>
+            Any other appenders (including Async) not in the above list create 
temporary objects during steady-state
+            logging. Use <a href="async.html">Async Loggers</a> to log 
asynchronously in a garbage-free manner.
+          </p>
         </subsubsection>
         <a name="Layouts" />
         <subsubsection name="Layouts">
           <h4>Layouts</h4>
           <p>
-            Supported layouts: only PatternLayout, and only the following 
conversion patterns:
+            From the built-in <a href="layouts.html">layouts</a>, currently 
only PatternLayout is garbage-free,
+            but only when used with the following conversion patterns.
           </p>
           <ul>
             <li>ClassNamePatternConverter</li>
@@ -130,81 +141,56 @@
             <li>ThreadNamePatternConverter</li>
             <li>ThreadPriorityPatternConverter</li>
           </ul>
+          <p>
+            Other PatternLayout conversion patterns, and some other Layouts 
are scheduled to be updated
+            to avoid creating temporary objects in a subsequent release.
+          </p>
+          <table><tr><td><b>Caution:</b> patterns containing regular 
expressions and lookups for property substitution
+            will result in temporary objects being created during steady-state 
logging.
+          </td></tr></table>
         </subsubsection>
-
-        <h4>Varargs and Unboxing</h4>
+        <a name="code" />
+        <subsubsection name="Application Code and Autoboxing">
+        <h4>Application Code and Autoboxing</h4>
         <p>
-          As of log4j-2.6, only a limited set of functionality is 
garbage-free. This set may grow in the future,
-          but for now only the following configuration does not allocate 
temporary objects during steady-state logging:
+          We made an effort to make existing application logging code 
garbage-free without requiring code changes,
+          but there is one area where this was not possible.
+          When logging primitive values (i.e. int, double, boolean, etc.),
+          autoboxing occurs and the JVM converts these primitive values to 
their Object wrapper equivalents.
         </p>
-        <ul>
-          <li>ThreadLocals are enabled (system property 
<tt>log4j2.enable.threadlocals</tt> is set to
-            <tt>true</tt>).
-          </li>
-          <li>Loggers are all asynchronous (system property 
<tt>Log4jContextSelector</tt> is set to
-            
<tt>org.apache.logging.log4j.core.async.AsyncLoggerContextSelector</tt>).
-          </li>
-          <li>The "steady-state" appenders are either 
<tt>RandomAccessFile</tt> or <tt>RollingRandomAccessFile</tt>.
-            Logging to any other appender, including <tt>FileAppender</tt> or 
<tt>ConsoleAppender</tt>,
-            will cause temporary objects to be created.</li>
-          <li>The Layout is a <tt>PatternLayout</tt> that uses one of the 
pre-defined date formats,
-            and does not contain regular expression replacements or 
lookups.</li>
-          <li>The configuration does not contain a <tt>&lt;Properties&gt;</tt> 
section.</li>
-        </ul>
         <p>
-          In addition to configuration, user code should follow these 
guidelines to be garbage-free:
+          Log4j provides an <tt>Unboxer</tt> utility to prevent autoboxing of 
primitive parameters.
+          This utility contains a thread-local pool of reused 
<tt>StringBuilder</tt>s.
+          The <tt>Unboxer.box(primitive)</tt> methods write directly into a 
StringBuilder, and
+          the resulting text will be copied into the final log message text 
without creating temporary objects.
         </p>
-        <p>
-          The following code snippet demonstrates garbage-free logging.
-          Note the use of Log4j's <tt>Unboxer</tt> utility to prevent 
auto-boxing of primitive parameters.
-        </p>
-        <pre class="prettyprint linenums">import 
org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.Marker;
-import static org.apache.logging.log4j.util.Unboxer.box;
-
-public class Usage {
-    private static final Logger logger = LogManager.getLogger("GarbageFree");
+        <pre class="prettyprint linenums">import static 
org.apache.logging.log4j.util.Unboxer.box;
 
-    public void garbageFree() {
-        logger.info("Simple string message");
-        logger.info("Message with {}", "parameters");
-        logger.info("Var-args {} {} {} {} {} {}", "are", "unrolled", "up", 
"to", "10", "parameters"); // etc up to 10 parameters
-        logger.info("Prevent primitive auto-boxing {} {}", box(10L), 
box(2.6d));
-        logger.info(() -> callExpensiveMethod());
-
-        // of course similarly for all log levels including custom log levels
-        logger.debug("debug level message");
-        logger.trace("trace level message");
-        logger.log(Level.forName("NOTICE", 345), "custom level message");
-    }
-...</pre>
-        <p>
-          However, not all logging is garbage free. Specifically:
-          <ul>
-            <li>Use no more than 10 parameters when logging a parameterized 
message to avoid vararg array creation.</li>
-            <li>Avoid using the ThreadContext map and stack for now since 
these are copy-on-write data structures by default.</li>
-            <li>Avoid the <tt>Logger.traceEntry</tt> and 
<tt>Logger.traceExit</tt> for now.</li>
-          </ul>
-        </p>
-        <pre class="prettyprint linenums">...
-    private static final String TOO_LARGE = new String(new char[519]);
-
-    public void notGarbageFree() {
-        logger.traceEntry("creates temporary objects");
-        logger.info(TOO_LARGE); // causes resize of internal StringBuilder, 
which will be trimmed back to 518 characters
-        logger.info("Messages containing '${': substituting a ${variable} 
creates temporary objects");
-
-        // a vararg array is created when logging a parameterized message with 
lambda parameters
-        logger.info("lambda value is {}", () -> callExpensiveMethod());
-
-        // a vararg array is created when logging more than 10 params
-        logger.info("{}{}{}{}{}{}{}{}{}{}{}", "1", "2", "3", "4", "5", "6", 
"7", "8", "9", "10", "11");
-        logger.info("Auto-boxing creates java.lang.Integer {} java.lang.Double 
{} etc", 987665, 3.14d);
-        ThreadContext.put("any", "thing"); // creates copy of the map
-        logger.traceExit("creates temporary objects");
-    }
-}</pre>
+...
+public void garbageFree() {
+    logger.debug("Prevent primitive autoboxing {} {}", box(10L), box(2.6d));
+}
+</pre>
+          <table><tr><td>
+            <p>
+              <b>Caution:</b> not all logging is garbage free. Specifically:
+            </p>
+            <ul>
+              <li>The ThreadContext map and stack are not garbage-free 
yet.</li>
+              <li>Logging more than 10 parameters creates vararg arrays.</li>
+              <li>Logging very large messages (more than 518 characters) when 
all loggers are Async Loggers
+                will cause the internal StringBuilder in the RingBuffer to be 
trimmed back to their max size.
+              </li>
+              <li>Logging messages containing '${': substituting a ${variable} 
creates temporary objects.</li>
+              <li>Logging a lambda <em>as a parameter</em>
+                (<tt>logger.info("lambda value is {}", () -> 
callExpensiveMethod())</tt>) creates a vararg array.
+                Logging a lambda expression by itself is garbage-free:
+                <tt>logger.debug(() -> callExpensiveMethod())</tt>.
+              </li>
+              <li>The <tt>Logger.traceEntry</tt> and <tt>Logger.traceExit</tt> 
methods create temporary objects.</li>
+            </ul>
+          </td></tr></table>
+        </subsubsection>
         <p>
         </p>
         <p>

Reply via email to