Hi Thomas,

I created a test case where I create 10 threads that are started approximately the same time and read 10 separate Blobs from a table (altogether 100 blobs). The test case is written in Beanshell and uses some of my utility classes so you are not capable of running it but you can check it out as pseudocode if you want (attached).

All threads report the same error:
Exception in thread "Thread-1" java.lang.OutOfMemoryError: Requested memory: 1952885510
   at org.h2.util.Utils.newBytes(Utils.java:364)
   at org.h2.store.Data.expand(Data.java:1119)
   at org.h2.store.Data.checkCapacity(Data.java:1114)
at org.h2.store.FileStoreInputStream.fillBuffer(FileStoreInputStream.java:100) at org.h2.store.FileStoreInputStream.readBlock(FileStoreInputStream.java:73)
   at org.h2.store.FileStoreInputStream.read(FileStoreInputStream.java:61)

I am quite convinced that these exceptions happen only when the reads are concurrent. When I limit the speed by writing to a slow output then I do not encounter errors.

I will now try with version 1.2.145 as you suggested but it is a bit more complicated in my case because I have to merge separately my own changes to source (which you did not accept as part of H2...)

- Rami

Thomas Mueller wrote:
Hi,

I think the problem is that you try to read from the LOB object after
going to the next row in the result set, or after closing the result
set or connection. If this is not the problem, could you try with H2
version 1.2.145? Could you create a reproducible test case?

Regards,
Thomas

import java.sql.*;
import rojares.toolbox.*;
import rojares.toolbox.util.*;
import rojares.toolbox.io.*;

class Loader {
    final long[] ids;
    final Connection conn;
    final NullOutputStream os = new NullOutputStream();
    Thread t;
    Loader(long[] ids) {
        this.ids = ids;
        this.conn = conn = DriverManager.getConnection(
            
"jdbc:h2:tcp://localhost/TV7;user=tv7;password=mannaIhme;schema=exodus"
        );
        this.t = new Thread() {
            public void run() {
                try {
                    for(int i=0; i<ids.length; i++) {
                        Statement stmt = conn.createStatement();
                        ResultSet rs = stmt.executeQuery("SELECT BYTES FROM 
IMAGE WHERE IMAGE_ID = " + ids[i]);
                        if (rs.next()) {
                            Blob blob = rs.getBlob(1);
                            InputStream bis = blob.getBinaryStream();
                            IOUtil.copyStream(bis, os);
                            Sys.log.info("X");
                        }
                        else Sys.log.errorln("Image id " + id + " was not 
found.");
                    }
                }
                catch (IOException ioe) {
                    // Let's just log these tersely
                    Sys.log.errorln(ioe.getMessage());
                }
                catch (SQLException sqle) {
                    Sys.log.errorln("Error occurred while reading image " + id 
+ " from database.", sqle);
                }
            }
        };
    }
    
    void start() {
        this.t.start();
    }
}

Class.forName("org.h2.Driver");
conn = 
DriverManager.getConnection("jdbc:h2:tcp://localhost/TV7;user=tv7;password=mannaIhme;schema=exodus");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT IMAGE_ID FROM IMAGE LIMIT 100");

Loader[] loaders = new Loader[10];

for(int i=0; i<10; i++) {
    long[] ids = new long[10];
    for(int j=0; j<10; j++) {
        rs.next();
        ids[j] = rs.getLong(1);
    }
    loaders[i] = new Loader(ids);
}

for(int i=0; i<10; i++) {
    loaders[i].start();
}
-- 
You received this message because you are subscribed to the Google Groups "H2 
Database" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/h2-database?hl=en.

Reply via email to