Subject RE: [Firebird-Java] Possible memory leak in EncodingFactory ?
Author Rick Debay
What happens when you roll back to the original EncodingFactory.java?
The first change to be tested should be in Encoding_OneByte. I doubt
pooling using a HashMap would help much (so I say after rereading my
original argument).

The new encodeToCharset has less code than the original, and the same
dynamic allocation of byte[]. The new decodeFromCharset has slightly
less code, but one dynamic allocation of char[], which would occur in
the original whenever more than 128 one byte characters were passed.

So I reason the slow-down must be in the pooling. It would get even
slower when changed to a SynchronizedHashMap or ConcurrentHashMap.
Let's test with just the memory reduction for now and see what those
numbers generate.

Once my home computer is working better than it is now, I promise to
contribute patches directly :-)

-----Original Message-----
From: Firebird-Java@yahoogroups.com
[mailto:Firebird-Java@yahoogroups.com] On Behalf Of Roman Rokytskyy
Sent: Tuesday, June 20, 2006 12:16 PM
To: Firebird-Java@yahoogroups.com
Subject: Re: [Firebird-Java] Possible memory leak in EncodingFactory ?

> Can you send me a diff? I'm curious how removing the working buffer
> slowed it down that much, primitive memory allocation isn't that bad
> in Java.

That's what I thought some time ago... I have managed to slow down
Jaybird twice by doing new byte[16384] in each operation (I wanted to
ensure that the communication buffer is not overwritten - I was looking
for a bug and that was the easiest solution to that problem). It took me
few days in profiler until I found the reason.

> Also it should have removed the need for one buffer. What JVM were
> you using?

Sun 1.4.2 - the one I use to build official releases.

The other thing wonders me more - the Encoding classes were not cached
in previous case, so I doubt that it reused the buffer a lot. It looks
like memory allocation during class instantiation (or with the constant
length) is less expensive than dynamic memory allocation...


The diff:

Index: EncodingFactory.java
===================================================================
RCS file:
/cvsroot/firebird/client-java/src/main/org/firebirdsql/encodings/Encodin
gFactory.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -r1.13 -r1.14
27a28,29
> public static final boolean USE_ENCODING_CACHING =
> Boolean.getBoolean("jaybird.encoding.cache");
>
116a119
> private static HashMap mainCache = new HashMap();
117a121,132
> if (USE_ENCODING_CACHING) {
> Encoding result = (Encoding)mainCache.get(encoding);
> if (result == null) {
> result = createEncodingInternal(encoding);
> mainCache.put(encoding, result);
> }
> return result;
> } else
> return createEncodingInternal(encoding);
> }
>
> public static Encoding createEncodingInternal(String encoding) {
214a230,231
> private static HashMap translatorCache = new HashMap();
>
215a233,245
> if (USE_ENCODING_CACHING) {
> Encoding result = (Encoding)translatorCache.get(encoding);
>
> if (result == null) {
> result = getEncodingInternal(encoding, charMapping);
> translatorCache.put(encoding, charMapping);
> }
>
> return result;
> } else
> return getEncodingInternal(encoding, charMapping);
> }
> public static Encoding getEncodingInternal(String encoding, char[]

> charMapping){
Index: Encoding_OneByte.java
===================================================================
RCS file:
/cvsroot/firebird/client-java/src/main/org/firebirdsql/encodings/Encodin
g_OneByte.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -r1.4 -r1.5
23a24,26
> * Revision 1.5 2006/06/20 06:34:00 rrokytskyy
> * added encoding caching that can be enabled via
> jaybird.encoding.cache property
> *
65,66c68,69
< byte[] bufferB = new byte[128];
< char[] bufferC = new char[128];
---
> byte[] sharedBufferB = new byte[128];
> char[] sharedBufferC = new char[128];
70,75c73,86
< if (bufferB.length < str.length())
< bufferB = new byte[str.length()];
< int length = encodeToCharset(str.toCharArray(), 0,
str.length(),
bufferB);
< byte[] result = new byte[length];
< System.arraycopy(bufferB, 0, result, 0, length);
< return result;
---
> if (EncodingFactory.USE_ENCODING_CACHING) {
> byte[] result = new byte[str.length()];
> encodeToCharset(str.toCharArray(), 0, str.length(),
result);
> return result;
> } else {
> if (sharedBufferB.length < str.length())
> sharedBufferB = new byte[str.length()];
>
> int length = encodeToCharset(str.toCharArray(), 0,
> str.length(), sharedBufferB);
>
> byte[] result = new byte[length];
> System.arraycopy(sharedBufferB, 0, result, 0, length);
> return result;
> }
88,91c99,108
< if (bufferC.length < in.length)
< bufferC = new char[in.length];
< int length = decodeFromCharset(in, 0, in.length, bufferC);
< return new String(bufferC, 0, length);
---
> if (EncodingFactory.USE_ENCODING_CACHING) {
> char[] bufferC = new char[in.length];
> int length = decodeFromCharset(in, 0, in.length, bufferC);
> return new String(bufferC, 0, length);
> } else {
> if (sharedBufferC.length < in.length)
> sharedBufferC = new char[in.length];
> int length = decodeFromCharset(in, 0, in.length,
> sharedBufferC);
> return new String(sharedBufferC, 0, length);
> }

Roman



------------------------ Yahoo! Groups Sponsor --------------------~-->
Check out the new improvements in Yahoo! Groups email.
http://us.click.yahoo.com/6pRQfA/fOaOAA/yQLSAA/saFolB/TM
--------------------------------------------------------------------~->


Yahoo! Groups Links