Re: Inserting large BLOBs via JDBC - OutOfMemoryError - Mailing list pgsql-jdbc

From Barry Lind
Subject Re: Inserting large BLOBs via JDBC - OutOfMemoryError
Date
Msg-id 3D5D2E77.3010902@xythos.com
Whole thread Raw
In response to Re: Inserting large BLOBs via JDBC - OutOfMemoryError  (hhaag@gmx.de)
List pgsql-jdbc

hhaag@gmx.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



pgsql-jdbc by date:

Previous
From: Barry Lind
Date:
Subject: Re: Inserting large BLOBs via JDBC - OutOfMemoryError
Next
From: Barry Lind
Date:
Subject: Re: Inserting large BLOBs via JDBC - OutOfMemoryError