logging-log4j-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Remko Popma <rem...@yahoo.com>
Subject Re: use of ThreadContext cleanup vs memory leaks etc
Date Thu, 01 Aug 2013 15:17:54 GMT
Curt,

I think the warning about memory leaks is mostly for short-lived threads. If you create a
new Thread often, put things in the ThreadContext and then let the thread die, things will
pile up in the ThreadContext.  If the threads from which you do logging essentially live
forever then don't worry about it.

ThreadContext has both a stack and a map. Personally I don't see much use for the stack, and
I only use the map methods:
* put(String, String)
* get(String)
* containsKey(String)
* remove(String)
* isEmpty()

The layout pattern for the map is %X(key) like you said. With the stack you only have patterns
to display the full stack contents (%x, %NDC).

Since beta7, both the stack and the map are copy-on-write implementations (avoiding the need
to copy the stack/map for every log event).
There is no ThreadContext#getStack() method, but there are the #getContext() and #getImmutableContext()
methods.
With the default (copy-on-write) implementations, getContext() creates a copy, and getImmutableContext()
returns a reference the underlying immutable map.
(That said, I don't see why you would need either of those methods. Just use the put/get/remove/...
methods on ThreadContext. In my app I only ever need to use ThreadContext#put().)

If you find out more about the difference in performance on j2me between log4j v1 and v2 I'd
be very interested, please keep us posted!

Hope this helps,
Remko


________________________________
 From: "SMITH, CURTIS" <cs0428@att.com>
To: "log4j-user@logging.apache.org" <log4j-user@logging.apache.org> 
Sent: Thursday, August 1, 2013 10:54 PM
Subject: use of ThreadContext cleanup vs memory leaks etc
 

Greetings,

A terse recap of performance on my J2ME on a slow single core env:  BasicContextSelector
and  BufferedIO=false for RollingFile DOES seem to equal log4j v1 performance in my most
recent benchmarks.  I'm not comfortable with this result because what happened is the V1
benchmarks jumped worse to equal the V2 benchmarks without explanation.  So I'm digging into
that issue.  But I'm wanting to move to using V2's MDC to see if that has much of a perf
hit for just put'ing a few variables into ThreadContext and referencing them in the Pattern: 
%X{transID}  etc

The log4j-users-guide.pdf does not have any MDC API discussion, just configuration parameters. 
This URL is all I've found:  http://logging.apache.org/log4j/2.x/manual/thread-context.html

Let me start by saying that most threads never die.  They wait on queues so I believe I never
have to worry about ThreadContext.clear / removeStack etc.   Or Do I??

But to clarify proper API use, the above URL infers that thread local object storage is cleaned
up with ThreadContext.clear()

Maybe it's left over from V1 NDC but the JavaDoc on ThreadContext has some strongly worded
recommendation for calling ThreadContext.removeStack()

"Each thread that created a diagnostic context by calling push(java.lang.String)<http://logging.apache.org/log4j/2.x/log4j-api/apidocs/org/apache/logging/log4j/ThreadContext.html>
should call this method before exiting. Otherwise, the memory used by the thread cannot be
reclaimed by the VM.

As this is such an important problem in heavy duty systems and because it is difficult to
always guarantee that the remove method is called before exiting a thread, this method has
been augmented to lazily remove references to dead threads. In practice, this means that you
can be a little sloppy and occasionally forget to call remove(java.lang.String)<http://logging.apache.org/log4j/2.x/log4j-api/apidocs/org/apache/logging/log4j/ThreadContext.html>
before exiting a thread. However, you must call remove sometime. If you never call it, then
your application is sure to run out of memory. "
I could use what the suggested cleanup of ThreadContext is??
Also:  there's no reasoning for the getStack() vs getImutableStack(),  my guess is one uses
a map.clone() and one doesn't.   I need to bridge the context Map around a queue so I do
need to get the Map and then put the map elements back into the servicing thread's context. 
I would like to avoid a map.clone/new Map if I can.  Which should I use:  getStack or getImutableStack?

Thanks, curt


Curt Smith
AT&T Digital Life
DLC Software Development
404-499-7013
(cell) 678-365-6508
Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message