【问题标题】:Memory management when using sqlite database in iphone在 iphone 中使用 sqlite 数据库时的内存管理
【发布时间】:2009-01-12 10:05:15
【问题描述】:

我的应用程序使用 SQLite 数据库来存储用户的输入。输入中的记录数将达到大约 100 条记录,并且我在应用程序中进行了大量 SQL 操作。

当我使用对象分配运行应用程序时,它显示 sqlite 库 libsqlite3.0.dylib 占用了大量内存。 libsqlite 框架会不会导致内存泄漏?与数据库通信的最佳方式是什么?有很多 sql 调用会增加我的应用程序的内存使用量。

谁能告诉我在应用程序中有效使用 sqlite 的最佳方法是什么。 (我使用 SQLiteBooks 示例作为参考)

谢谢。

【问题讨论】:

    标签: iphone sqlite


    【解决方案1】:

    Sqlite 对请求使用缓存。不时关闭并重新打开数据库以释放缓存内存。

    除非你的内存要求很高,否则你不应该关心。

    您可以在 UIApplicationDelegate 方法 applicationDidReceiveMemoryWarningUIViewController 委托方法 didReceiveMemoryWarning

    中捕获关键条件

    如果调用了这些方法之一,请关闭并重新打开数据库。

    【讨论】:

    • 谢谢斯蒂芬。但是如果我这样做并且有一些查询没有完全执行,操作会回滚还是完成然后关闭数据库?
    • 如果使用带有 BEGIN ... COMMIT 的事务,如果数据库关闭,事务将 ROLLBACK。
    • 嗨,斯蒂芬。关闭数据库并再次打开会给出此异常stackoverflow.com/questions/449933/…
    【解决方案2】:

    我没有看到任何由 sqlite 引起的内存泄漏。它确实使用了合理的内存块,但想想你需要编写多少代码以及需要缓存多少数据来做同样的事情......

    最好的建议是使用高效的 SQL 并尽快重置语句句柄。完成您准备好的陈述也可能会有所帮助,尽管我还没有发现这样做的必要。

    人们经常建议定期关闭和重新打开数据库。虽然这不会造成伤害,但我自己并没有看到任何实际的好处。

    最后,在 sqlite 网站上,您会看到关于 functions to manage memory 的讨论。这些听起来很诱人,直到您意识到它们是可选的并且在 iPhone 的默认构建中未启用。

    【讨论】:

    • 谢谢斯蒂芬。我没有缓存数据库中的任何数据,并且所有数据仅在需要时才读取。语句的功能结束后也会立即进行重置。我也在敲定声明。还有其他建议吗?再次感谢。
    【解决方案3】:

    【讨论】:

    • PRAGMA 对 iPhone 没有帮助,因为 Apple 提供了二进制库。
    • PRAGMA 在运行时执行,而不是在编译时执行
    【解决方案4】:

    在连续执行许多 INSERT (> 1000) 时,我在 SQLite 中的内存使用量猛增。写入性能也很慢。通过将执行 INSERT 的循环包装在事务中,这些问题几乎完全消除了。我为此发布了一些示例代码以响应this question

    【讨论】:

    • 这是因为 SQLite 使用其页面缓存的方式。如果您将 INSERT/UPDATE 语句放在事务中,它只会在内存中进行修改,然后在您提交时将它们批量写入。如果您没有显式事务,SQLite 会在每个 INSERT、UPDATE 或 DELETE 周围放置一个隐式事务。此外,SQLite 始终会更新整个 4k 的数据库页面,即使您只修改了该页面中的一点数据。
    【解决方案5】:

    真的想要限制 iphone 应用程序中 sqlite 的缓存大小。当您启动应用程序并初始化数据库时,运行如下命令:

    const char *pragmaSql = "PRAGMA cache_size = 50";
    if (sqlite3_exec(database, pragmaSql, NULL, NULL, NULL) != SQLITE_OK) {
        NSAssert1(0, @"Error: failed to execute pragma statement with message '%s'.", sqlite3_errmsg(database));
    }
    

    这将防止 sqlite 缓存您的查询并慢慢消耗您的所有内存。

    【讨论】:

    • 在执行每个 sql 事务时我应该这样做吗??
    【解决方案6】:

    在我拥有一个相对较大的数据库之前,由于索引不佳,我曾看到内存使用量激增。如果您在数据库中添加一些经过深思熟虑的索引,这是一种在现实世界中恢复内存使用的快速简便的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-25
      • 2011-07-25
      • 1970-01-01
      • 2011-04-10
      • 2011-10-10
      • 2010-10-28
      相关资源
      最近更新 更多