微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

LiteDb.Engine.PageBuffer 内存泄漏

如何解决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.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?