[Vala] SQLHeavy memory leak?



Hi all,

I have the classic Gtk "enormous TreeView backed by SQL database"
problem, which I've attempted to solve with the entirely excellent
SQLHeavy and the accompanying TreeModel it provides.

It works very well, but I have a catastrophic memory leak. Hunting the
problem down, it seems to be SQLHeavy.Query that is the culprit.

In an attempt to distill the problem to its essentials, I crufted up
the attached program; it's nonsense in that all it does is create lots
of Queries and throw them away, but if I run it as 'dbtest 0' my
memory usage is 1.3MB, and with 'dbtest 100000' it's 171MB.

I've tried fiddling with the various db options, they don't seem to be
especially relevant.

Am I doing something fundamentally stupid, or is this a leak?

cheers
ant

using Gtk;

class Main : GLib.Object {

    public int queries = 0;
    public SQLHeavy.Database db;
    public SQLHeavy.Transaction trans;
    public SQLHeavy.Query ins_query;

    public Main(int n) {
        queries = n;
    }

    public void run() {

        try {
            db = new SQLHeavy.Database("test.sqlite");
            db.sql_executed.connect((sql) => { debug("::%s", sql); });

            /* make it as speedy as possible */
            db.synchronous = SQLHeavy.SynchronousMode.OFF; // don't
wait for disk writes
            db.count_changes = false; // don't return number of rows
changed for INSERT, UPDATE, DELETE
            db.temp_store = SQLHeavy.TempStoreMode.MEMORY; // store
temp tables and indices in RAM
            db.journal_mode = SQLHeavy.JournalMode.OFF; // disable journalling
            db.cache_size = 8000; // allow 8000 1KB pages for cache
            db.enable_profiling = false;

            /*db.auto_vacuum = SQLHeavy.AutoVacuum.FULL;*/ // makes no
difference

            db.execute("DROP TABLE IF EXISTS `log`");
            db.execute("CREATE TABLE `log` ( `secs` INTEGER, `msecs`
INTEGER )");

            trans = db.begin_transaction();
            ins_query = trans.prepare("INSERT INTO log VALUES(?,?);");

            /* create some records */
            for(var i = 0; i < 10; i++) {
                ins_query.bind_int(0, 42);
                ins_query.bind_int(1, 42);
                ins_query.execute();
            }
            trans.commit();

            /* create some queries */
            for(var i = 0; i < queries; i++) {
                SQLHeavy.Query q = db.prepare("SELECT `ROWID` FROM log");
                /*q.clear();*/ // makes no difference
            }
            stderr.printf("done, %d queries\n", queries);

        } catch(SQLHeavy.Error err) {
            error(err.message);
        }
    }

    public static int main(string[] args) {

        Gtk.init(ref args);
        Main app = new Main(args[1].to_int());
        app.run();
        Gtk.main();

        return 0;
    }
}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]