Re: Inserting large BLOBs via JDBC - OutOfMemoryError

From: Barry Lind <barry(at)xythos(dot)com>
To: hhaag(at)gmx(dot)de
Cc: pgsql-jdbc(at)postgresql(dot)org
Subject: Re: Inserting large BLOBs via JDBC - OutOfMemoryError
Date: 2002-08-16 16:55:19
Message-ID: 3D5D2E77.3010902@xythos.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-jdbc

hhaag(at)gmx(dot)de wrote:

>I think it's at least better than initializing the stringbuffer with the
>default capacity, which is 16. And as long as the stringbuffer is used only
>internally (as a local variable) in a private method, no other parts of the code
>should be affected. Of course you cannot predict the final size of the
>created string.
>
I agree. I will check in a patch for this later today.

>There are also other places where StringBuffer usage could be improved in my
>opinion:
>
>(1) org.postgresql.jdbc1.AbstractJdbc1Statement#setString()
>
> // Some performance caches
> private StringBuffer sbuf = new StringBuffer();
>...
>
>current:
>
> public void setString(int parameterIndex, String x) throws SQLException {
> ....
> synchronized (sbuf) {
> sbuf.setLength(0);
>
>
>proposed:
>
> StringBuffer sbuf = new StringBuffer(x.length());
>
>--> use a local, non-synchronized variable. initialize the stringbuffer with
>a smart capacity.
>
>
The use of the member variable sbuf is there to solve the same problem.
Instead of creating new StringBuffers every time you call setString()
in a PreparedStatement it reuses the one object thus leading to less
object creation and less memory usage. However as above it probably
makes sense to not use the default size, and to call ensureCapacity() to
resize it before use. I will check in fixes for this today as well.

>(2) org.postgresql.jdbc1.AbstractJdbc1Statement#compileQuery()
>
>
>protected synchronized String compileQuery()
>throws SQLException
>{
> sbuf.setLength(0);
> int i;
>
> if (isFunction && !returnTypeSet)
> throw new PSQLException("postgresql.call.noreturntype");
> if (isFunction) { // set entry 1 to dummy entry..
> inStrings[0] = ""; // dummy entry which ensured that no one overrode
> // and calls to setXXX (2,..) really went to first arg in a function
>call..
> }
>
> for (i = 0 ; i < inStrings.length ; ++i)
> {
> if (inStrings[i] == null)
> throw new PSQLException("postgresql.prep.param", new Integer(i + 1));
> sbuf.append (templateStrings[i]).append (inStrings[i]);
> }
> sbuf.append(templateStrings[inStrings.length]);
> return sbuf.toString();
>}
>
>
>also in this case the stringbuffer should be initialized with a smart
>capacity.
>
>
>
This one is a little tricky. I am open to suggestions on what would be
reasonable.

thanks,
--Barry

In response to

Browse pgsql-jdbc by date

  From Date Subject
Next Message Barry Lind 2002-08-16 16:58:13 Re: Inserting large BLOBs via JDBC - OutOfMemoryError
Previous Message Barry Lind 2002-08-16 16:05:34 Re: Inserting large BLOBs via JDBC - OutOfMemoryError