You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ws.apache.org by "Andreas Veithen (JIRA)" <ji...@apache.org> on 2011/09/18 21:11:08 UTC

[jira] [Resolved] (AXIOM-390) Memory leak in UIDGenerator

     [ https://issues.apache.org/jira/browse/AXIOM-390?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Andreas Veithen resolved AXIOM-390.
-----------------------------------

    Resolution: Invalid

The leak reported by Tomcat is a false positive. The original implementation of the UIDGenerator indeed caused a class loader leak, but that has been fixed in 1.2.12 (see AXIOM-354).

A thread local only causes a class loader leak if certain conditions are met, as described in [1]. However, condition 2 is not met here because the value of the thread local is of type long[]. Unfortunately, Tomcat is not able to check that condition and reports a false positive.

[1] http://code.google.com/p/arit/wiki/ThreadLocal

> Memory leak in UIDGenerator
> ---------------------------
>
>                 Key: AXIOM-390
>                 URL: https://issues.apache.org/jira/browse/AXIOM-390
>             Project: Axiom
>          Issue Type: Bug
>          Components: API
>    Affects Versions: 1.2.12
>         Environment: Tomcat 7.0.21, Axis2 1.6.1 with Axiom 1.2.12
>            Reporter: Detlef Günther
>
> Shutting down tomcat produces a list of error messages for each request of a web service:
> 16.09.2011 08:36:16 org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
> SCHWERWIEGEND: The web application [/datatransfer] created a ThreadLocal with key of type [org.apache.axiom.util.UIDGenerator$1] (value [org.apache.axiom.util.UIDGenerator$1@252a78ee]) and a value of type [long[]] (value [[J@7696452]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak. 
> Problem seems to be ThreadLocal, which cannot bee cleaned up after processing the request. Eliminating ThreadLocal solves the problem:
> public final class UIDGenerator {
> 	//	private static final long				startTimeXorOperand;
> 	private static final long				threadIdXorOperand;
> 	private static final long				seqXorOperand;
> 	static {
> 		Random rand = new Random();
> 		threadIdXorOperand = rand.nextLong();
> 		//		startTimeXorOperand = rand.nextLong();
> 		seqXorOperand = rand.nextLong();
> 	}
> 	private final static AtomicLong	seqValue	= new AtomicLong(0);
> 	private UIDGenerator() {
> 	}
> 	private static void writeReverseLongHex(long value, StringBuilder buffer) {
> 		for (int i = 0; i < 64; i += 4) {
> 			int n = (int) (value >> i) & 0xF;
> 			buffer.append((char) (n < 10 ? '0' + n : 'a' + n - 10));
> 		}
> 	}
> 	/**
> 	 * Generate a unique ID as hex value and add it to the given buffer. Note that
> 	 * with respect to the triplet, the order of nibbles is reversed, i.e. the
> 	 * least significant nibble of the sequence is written first. This makes
> 	 * comparing two IDs for equality more efficient.
> 	 * 
> 	 * @param buffer
> 	 */
> 	private static void generateHex(StringBuilder buffer) {
> 		writeReverseLongHex(seqValue.incrementAndGet() ^ seqXorOperand, buffer);
> 		writeReverseLongHex(Thread.currentThread().getId() ^ threadIdXorOperand,
> 				buffer);
> 	}
> ...
>  

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

       

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