[
https://issues.apache.org/jira/browse/IO-468?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14312252#comment-14312252
]
Thomas Neidhart edited comment on IO-468 at 2/9/15 2:08 PM:
------------------------------------------------------------
I am sorry, but you got so many pointers to the actual problem with
ThreadLocals and you still don't get it. Hint: it is not the WeakReferences.
Take your time and read the material in detail!
Edit:
When retrieving a value from a ThreadLocal variable, the actual ThreadLocal
instance is added as a direct reference to the current Thread. This is
especially bad in a servlet container, where the threads are usually not killed
but re-used in a ThreadPool. This means the Thread never gets killed, thus the
ThreadLocal never gets cleaned up. This would not be so bad if it would only be
about 4KB (the allocated byte array), but if you sub-class ThreadLocal, it is
loaded by your web application classloader, which is also referenced by this
instance (see Class.getClassLoader()). Now you probably realize what this
means: the thread has now an indirect reference from the ThreadLocal to the
ClassLoader, which contains all loaded classes of the web app. This is
extremely bad as it means the web app ClassLoader (and everything he has a
reference to, which is quite a lot) will never be garbage-collected. Voila, big
mess.
But yeah, we gained ~2ns of allocation time.
was (Author: tn):
I am sorry, but you got so many pointers to the actual problem with
ThreadLocals and you still don't get it. Hint: it is not the WeakReferences.
Take your time and read the material in detail!
> Avoid allocating memory for method internal buffers, use threadlocal memory
> instead
> -----------------------------------------------------------------------------------
>
> Key: IO-468
> URL: https://issues.apache.org/jira/browse/IO-468
> Project: Commons IO
> Issue Type: Improvement
> Components: Utilities
> Affects Versions: 2.4
> Environment: all environments
> Reporter: Bernd Hopp
> Priority: Minor
> Labels: newbie, performance
> Fix For: 2.5
>
> Attachments: PerfTest.java, monitoring_with_threadlocals.png,
> monitoring_without_threadlocals.png, performancetest.ods,
> performancetest_weakreference.ods
>
> Original Estimate: 12h
> Remaining Estimate: 12h
>
> In a lot of places, we allocate new buffers dynamically via new byte[]. This
> is a performance drawback since many of these allocations could be avoided if
> we would use threadlocal buffers that can be reused. For example, consider
> the following code from IOUtils.java, ln 2177:
> return copyLarge(input, output, inputOffset, length, new
> byte[DEFAULT_BUFFER_SIZE]);
> This code allocates new memory for every copy-process, that is not used
> outside of the method and could easily and safely reused, as long as is is
> thread-local. So instead of allocating new memory, a new utility-class could
> provide a thread-local bytearray like this:
> byte[] buffer = ThreadLocalByteArray.ofSize(DEFAULT_BUFFER_SIZE);
> return copyLarge(input, output, inputOffset, length, buffer);
> I have not measured the performance-benefits yet, but I would expect them to
> be significant, especially when the streams itself are not the performance
> bottleneck.
> Git PR is at https://github.com/apache/commons-io/pull/6/files
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)