Subject | Re[2]: [Firebird-Java] Possible memory leak in EncodingFactory ? |
---|---|
Author | Alexey Panchenko |
Post date | 2006-06-21T07:49:25Z |
Roman Rokytskyy wrote:
encodeToCharset() - any way result should be allocated.
Index: Encoding_OneByte.java
===================================================================
RCS file: /cvsroot/firebird/client-java/src/main/org/firebirdsql/encodings/Encoding_OneByte.java,v
retrieving revision 1.5
diff -u -r1.5 Encoding_OneByte.java
--- Encoding_OneByte.java 20 Jun 2006 06:34:00 -0000 1.5
+++ Encoding_OneByte.java 21 Jun 2006 06:54:26 -0000
@@ -65,25 +65,13 @@
}
}
- byte[] sharedBufferB = new byte[128];
char[] sharedBufferC = new char[128];
// encode
public byte[] encodeToCharset(String str){
- 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;
- }
}
public abstract int encodeToCharset(char[] in, int off, int len, byte[] out);
Roman, where I can download the AS3AP benchmark test you used? I want
to check the speed of encodeToCharset() passing the String instead of
char[] - this way we can avoid new memory allocation in
str.toCharArray().
And lets continue about caching. I want to describe how it can be
implemented and if we agree on the way - I will make the patch.
1) Always use sharedBufferC in Encoding_OneByte
2) Cache Encoding objects in GDSHelper, so all fields of the
connection use the same object.
3) Remove the
protected String iscEncoding = null;
protected String javaEncoding = null;
protected String mappingPath = null;
from each FBField - they are obtained from GDSHelper and are needed
only for encoding/decoding the strings.
4) Move methods encodeString/decodeString from XSQLVAR to FBField
5) Implement in GDSHelper the caching method getEncoding() it would
call non-caching implementaion in EncodingFactory and save obtained
object for reuse.
The problems:
1) In the current implementation every field uses default database
encoding - the field encoding is not used. Is it intentional
optimization ?
2) Is there any chance somebody will be using different objects
belonging to the same connection from different threads?
The code in decodeFromCharset is not thread safe intentionally, so if
it is the common use case to work with connection from different
threads (I personally always use each connection on the single thread)
the Encoding caching should be done per Statement/ResultSet objects.
What do you think ?
--
Best regards,
Alexey mailto:alex+news@...
> The number are comparable. I guess we stop here. The implementation ofFirst of all, there is no need to have sharedBufferB in
> Encoding interface will be "cached" for the lifetime of the XSQLVAR object,
> won't have allocated memory except the one for the object itself.
encodeToCharset() - any way result should be allocated.
Index: Encoding_OneByte.java
===================================================================
RCS file: /cvsroot/firebird/client-java/src/main/org/firebirdsql/encodings/Encoding_OneByte.java,v
retrieving revision 1.5
diff -u -r1.5 Encoding_OneByte.java
--- Encoding_OneByte.java 20 Jun 2006 06:34:00 -0000 1.5
+++ Encoding_OneByte.java 21 Jun 2006 06:54:26 -0000
@@ -65,25 +65,13 @@
}
}
- byte[] sharedBufferB = new byte[128];
char[] sharedBufferC = new char[128];
// encode
public byte[] encodeToCharset(String str){
- 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;
- }
}
public abstract int encodeToCharset(char[] in, int off, int len, byte[] out);
Roman, where I can download the AS3AP benchmark test you used? I want
to check the speed of encodeToCharset() passing the String instead of
char[] - this way we can avoid new memory allocation in
str.toCharArray().
And lets continue about caching. I want to describe how it can be
implemented and if we agree on the way - I will make the patch.
1) Always use sharedBufferC in Encoding_OneByte
2) Cache Encoding objects in GDSHelper, so all fields of the
connection use the same object.
3) Remove the
protected String iscEncoding = null;
protected String javaEncoding = null;
protected String mappingPath = null;
from each FBField - they are obtained from GDSHelper and are needed
only for encoding/decoding the strings.
4) Move methods encodeString/decodeString from XSQLVAR to FBField
5) Implement in GDSHelper the caching method getEncoding() it would
call non-caching implementaion in EncodingFactory and save obtained
object for reuse.
The problems:
1) In the current implementation every field uses default database
encoding - the field encoding is not used. Is it intentional
optimization ?
2) Is there any chance somebody will be using different objects
belonging to the same connection from different threads?
The code in decodeFromCharset is not thread safe intentionally, so if
it is the common use case to work with connection from different
threads (I personally always use each connection on the single thread)
the Encoding caching should be done per Statement/ResultSet objects.
What do you think ?
--
Best regards,
Alexey mailto:alex+news@...