LiteDb.Engine.PageBuffer 内存泄漏

问题描述

我们正在使用 LiteDB 运行一个简单的 PoC,它同时读取/写入/更新本地数据库

由于 8Kb LiteDb.Engine.PageBuffer 对象,这会导致无限且非常快的内存泄漏。

按顺序而不是异步执行这些操作不会导致内存泄漏。

这里有人有什么想法吗?这并不意味着我们需要为所有数据库操作实现一个队列以避免内存泄漏。

泄漏代码(异步操作):

public class TestTable1
{ 
    public Guid Id { get; set; }
    public string Property1 { get; set; }
    public int Property2 { get; set; }
}

public class Tester
{
    private System.Timers.Timer _timerWrite;
    private System.Timers.Timer _timerUpdate;
    private System.Timers.Timer _timerRead;


    private LiteDatabase _db;

    public void Start()
    {
        var connectionString = new ConnectionString() { Filename = @"D:\temp\_db",Connection = ConnectionType.Direct,Upgrade = true };
        _db = new LiteDatabase(connectionString);

        _timerWrite = new System.Timers.Timer { Interval = 1000 };
        _timerWrite.Elapsed += _timerWrite_Elapsed;
        _timerWrite.Start();

        _timerRead = new System.Timers.Timer { Interval = 500 };
        _timerRead.Elapsed += _timerRead_Elapsed;
        _timerRead.Start();

        _timerUpdate = new System.Timers.Timer { Interval = 100 };
        _timerUpdate.Elapsed += _timerUpdate_Elapsed;
        _timerUpdate.Start();

    }

    private void _timerUpdate_Elapsed(object sender,ElapsedEventArgs e)
    {
        var table = _db.GetCollection<TestTable1>();
        _timerUpdate.Stop();
        var i = 0;
        var rows = table.Find(x => x.Property2 > 25);
        foreach (var row in rows)
        {
            row.Property1 += "updated";
            table.Update(row);
            i++;
        }

        Console.WriteLine($"Updated {i} rows from table ...");
        _timerUpdate.Start();
    }

    private void _timerRead_Elapsed(object sender,ElapsedEventArgs e)
    {
        var table = _db.GetCollection<TestTable1>();
        _timerRead.Stop();
        var rows = table.Find(x => x.Property2 > 25);

        Console.WriteLine($"Read {rows.Count()} rows from table ...");
        _timerRead.Start();
    }

    private void _timerWrite_Elapsed(object sender,ElapsedEventArgs e)
    {
        var table = _db.GetCollection<TestTable1>();
        _timerWrite.Stop();
        for (var i = 0; i < 100; i++)
        {
            table.Insert(new TestTable1() { Id = Guid.NewGuid(),Property1 = i.ToString(),Property2 = i });
        }

        Console.WriteLine("Added 100 new rows to collection");
        _timerWrite.Start();
    }

    public void Stop()
    {
        _timerUpdate.Elapsed -= _timerUpdate_Elapsed; _timerRead.Elapsed -= _timerRead_Elapsed; _timerWrite.Elapsed -= _timerWrite_Elapsed;
        _timerWrite.Stop(); _timerRead.Stop(); _timerUpdate.Stop();
        _timerUpdate?.dispose(); _timerRead?.dispose(); _timerWrite?.dispose();

        _db.dispose();
    }
}

不泄漏代码(顺序操作)

public class Tester
{
    private System.Timers.Timer _timerAll;


    private LiteDatabase _db;

    public void Start()
    {
        var connectionString = new ConnectionString() { Filename = @"D:\temp\_db",Upgrade = true };
        _db = new LiteDatabase(connectionString);

        _timerAll = new System.Timers.Timer { Interval = 100 };
        _timerAll.Elapsed += _timerAll_Elapsed;
        _timerAll.Start();
    }

    private void _timerAll_Elapsed(object sender,ElapsedEventArgs e)
    {
        // update
        var table = _db.GetCollection<TestTable1>();
        _timerAll.Stop();
        var i = 0;
        var rows = table.Find(x => x.Property2 > 25);
        foreach (var row in rows)
        {
            row.Property1 += "updated";
            table.Update(row);
            i++;
        }
        Console.WriteLine($"Updated {i} rows from table ...");

        // read
        rows = table.Find(x => x.Property2 > 25);

        // write            
        for (i = 0; i < 100; i++)
        {
            table.Insert(new TestTable1() { Id = Guid.NewGuid(),Property2 = i });
        }
        Console.WriteLine("Added 100 new rows to collection");

        _timerAll.Start();

    }

    public void Stop()
    {
        _timerAll.Elapsed -= _timerAll_Elapsed;
        _timerAll.Stop();
        _timerAll?.dispose();
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...