Objective-C - 如何在iOS模拟器上强制低内存?

8

我遇到了一个错误,一些用户在设备内存不足时会出现EXC_BAD_ACCESS。堆栈跟踪指向下面的if行,我认为这是因为被释放但仍在使用的UTF8String:

dispatch_sync(dbQueue, ^{
    if (sqlite3_bind_text(sql_stmt, 1, pid.UTF8String, -1, SQLITE_STATIC) != SQLITE_OK) {
...

我很难在我的设备或模拟器上复现这个问题,有什么方法可以强制或模拟低内存情况吗?

更新:

我已经尝试在上面的行上设置断点,然后使用“模拟内存警告”选项,但我仍然无法复现EXC_BAD_ACCESS错误。

4个回答

4
在模拟器中有一个菜单项:硬件:模拟内存警告。
或者使用快捷键:Shift+Command+M

3
在模拟器菜单中: 硬件-> 模拟内存警告更新 如果你确定你的应用程序在sqlite3_bind_text处崩溃,我认为最有可能的问题是pid.UTF8String有时为NULL,这会导致崩溃。此外,当使用pid或pid.UTF8String时,它们不太可能被释放,您可以检查崩溃报告(如果有)并检查导致EXC_BAD_ACCESS的内存地址,例如如果您有EXC_BAD_ACCESS CODE=2 ADDRESS=0x00000000,这意味着pid.UTF8String确实是一个空指针,如果地址不是0x0,则是另一个问题(在您的情况下非常不可能)。
作为建议,请在您的代码中添加nil检查:
if (pid) {
    if (sqlite3_bind_text(sql_stmt, 1, pid.UTF8String, -1, SQLITE_STATIC) != SQLITE_OK){
    // do your stuff
    }
} else {
    sqlite3_bind_null(sql_stmt,1);
}

根据我的理解,该选项只会引发一个警告并调用一个名为didReceiveMemoryWarning的方法,但它是否也重现了低内存设备的相同行为呢? - heitortsergent
1
感谢@MaxvonHippel提供的链接!我尝试使用此选项并更新了问题,但仍无法重现EXC_BAD_ACCESS错误。 - heitortsergent
1
模拟内存警告不会导致内存分配失败,也可能无法帮助您跟踪内存问题。 - Mike Weller
截至2023年6月,菜单项现在位于“调试”菜单中。 - jezmck

0

在您的Xcode屏幕左侧,您可以看到一个按钮,用于打开调试导航器,在那里您可以查看您的应用程序当前使用的内存量以及可用的内存量。

如果您进行分析,您会发现模拟器的可用内存与计算机的可用内存相同,因此我建议您同时运行一些使用大量内存的应用程序和模拟器。

如果您有一个iPad可用,这可能更容易,我通常会访问网站并尽可能多地复制Unicode表,以便将其存储在剪贴板中。


0
很多时候,这些错误是由一系列“完美风暴”情况造成的(例如竞态条件、在恰当时间运行的不频繁任务等),通常是你无法预料到的情况;如果你知道如何可靠地重现它,你可能也知道如何修复它。你能希望的下一个最好的事情就是尝试在一个环境中增加你重现它的统计概率(调试器),在那里你可以希望理解正在发生的事情。
参见此帖子:iOS开发:如何在设备上引发低内存警告?。通过编程模拟内存警告,你可以(例如)使用重复定时器每秒钟引发一次内存警告(速度更快可能会遇到其他问题,这将让你追逐自己的尾巴而不是解决原始问题),消除了手动重复操作的需要。
在实际运行测试之前,你还可以在以下位置设置断点:
Symbol                                        Module
======                                        ======
objc_exception_throw                          libobjc.A.dylib
-[NSException raise]                          CoreFoundation

此外,还需在所有Objective-C异常上设置断点。设置断点将允许您在运行时抛出异常之前检查内存内容,从而在发生问题时更有可能理解问题的根源。当(如果)捕获崩溃时,请检查pid,pid.UTF8String和sql_stmt,因为它们看起来最有可能是罪魁祸首。
运行您的应用程序并启动计时器。这不一定会直接导致您正在寻找的崩溃,但它可能使其随着时间的推移更有可能发生,而无需手工操作;您可以启动计时器并等待(即做更有意义的事情),直到您实际看到崩溃。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接