On 1:59 PM, Christopher Schultz wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

All,

I've got a servlet that needs to log every request (potentially big
requests) to files on the disk. In order to do that in a
reasonably-tidy way, we write each file into a directory with the
current date in the path, something like this:

.../logs/2011-11-23/request-XYX.log

To do this, we have a SimpleDateFormat object that we use to ensure we
target the right directory. Since SimpleDateFormat isn't threadsafe,
we have two choices: synchronize or use ThreadLocal. We have opted for
the latter: ThreadLocal.

Our servlet defines the ThreadLocal to be protected (because this is a
base class for several servlets that all do similar things) and
transient (because we just don't need it to be serialized) and
override the initialValue method, like this:

     protected transient ThreadLocal<SimpleDateFormat>  dayFormat = new
ThreadLocal<SimpleDateFormat>() {
         public SimpleDateFormat initialValue()
         {
             return new SimpleDateFormat("yyyy-MM-dd");
         }
     };

In the servlet's destroy method, we dutifully call dayFormat.remove().
Tomcat complains that we are leaving sloppy ThreadLocals around on
shutdown. Duh: Servlet.destroy is called by a single thread and won't
actually remove the ThreadLocal in any meaningful way.

So, my question is whether or not there is a good way to clean-out the
ThreadLocals from our webapp?

Given the declaration above, we are creating a new class which will be
loaded by our webapp's ClassLoader and therefore pinning that
ClassLoader in memory definitely causing a memory leak across reploy
cycles.

One way to avoid this would be to have a library at the server-level
that only contains this simple ThreadLocat<SimpleDateFormat>
definition, but that seems like kind of an awkward solution.

Removing the ThreadLocal after every request of course means that the
use of ThreadLocal is entirely useless.

Should I stop worrying about the overhead of creating a
SimpleDateFormat? Should I look for a threadsafe implementation of
SimpleDateFormat (maybe in commons-lang or something)? Should I
synchronize access to the object?

Any suggestions would be very helpful.

Thanks,
- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk7NFcAACgkQ9CaO5/Lv0PDIoACgrc5nNYGXUxjJ+hz1kWpiIL6J
SpYAoJQ6dcxCi4WmPX+1BJs9b3c+UQB5
=3bj2
-----END PGP SIGNATURE-----

Hi, Chris-

This sounds very similar to the problem I faced when trying to terminate an executor in contextDestroyed. I worked around that by calling Thread.yield() after terminating the executor.

    public void contextDestroyed( ServletContextEvent sce )
    {
        if ( executor != null )
        {
            boolean isTerminated = false;

            executor.shutdown();

            do
            {
                try
                {
                    isTerminated = executor.awaitTermination(
                        1, TimeUnit.SECONDS );
                }
                catch ( InterruptedException ignore )
                {
                }
            }
            while ( !isTerminated );

            executor = null;

            Thread.yield();
        }
    }

Adding Thread.yield() eliminated the error message from the log.

Hope that helps.

-Terence Bandoian


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to