【发布时间】:2019-09-04 02:11:13
【问题描述】:
我一直试图在 iOS 上找到内存泄漏,我 99% 是在 TScrollBox 或 TChart 中。导致崩溃的动作是简单地在 TChart 上来回滚动。应用在 Win32 环境下运行良好,内存使用稳定。
iOS 上的崩溃原因是 EXC_RESOURCE -> myappname[5548] 超出内存限制:每个 Xcode 控制台的 ActiveHard 1400MB(致命)。
为了排除我的意大利面条代码作为罪魁祸首,我创建了一个简单的项目来重现错误,它也崩溃了。以下是 Xcode 控制台输出的片段。我收到大量断言,然后收到内存警告,然后 iOS 内核杀死了我的应用程序 (Project1)。
default 20:28:26.180333 -0500 assertiond [Project1:7693] Activate assertion: <BKProcessAssertion: 0x12b0102c0; "com.apple.UIKit.KeyboardManagement.message" (finishTask:180s); id:…8EA7F5E94DD5>
default 20:28:26.180542 -0500 assertiond [Project1:7693] Setting jetsam priority to 10 [0x10108]
default 20:28:26.182151 -0500 assertiond [Project1:7693] Deactivate assertion: <BKProcessAssertion: 0x12b0102c0; "com.apple.UIKit.KeyboardManagement.message" (finishTask:180s); id:…8EA7F5E94DD5>
default 20:28:26.182312 -0500 assertiond [Project1:7693] Setting jetsam priority to 10 [0x10100]
default 20:28:26.183307 -0500 assertiond [Project1:7693] Remove assertion: <BKProcessAssertion: 0x12b0102c0; "com.apple.UIKit.KeyboardManagement.message" (finishTask:180s); id:…8EA7F5E94DD5>
default 20:28:32.609723 -0500 Project1 Received memory warning.
不久之后,我看到以下控制台消息:
默认 20:28:45.881914 -0500 内核 EXC_RESOURCE -> Project1[7693] 超出内存限制:ActiveHard 1400 MB(致命)。
我的崩溃测试应用是在 C++ Builder 10.3.2 中构建的简单 Firemonkey 应用。
A) 在表单 (Panel1) 上放置一个 TPanel。
B) 在 Panel1 (ScrollBox1) 上放置一个 TScrollBox。将其对齐设置为 Contents。
C) 在 ScrollBox1 (Layout1) 上放置一个 TLayout。将其对齐设置为无。将其宽度设置为 2100。
D) 在 Layout1 上放置一个 TChart。将其高度设置为 200,宽度 7300。将其对齐设置为无。
E) 给Form1添加一个TToolBar,并在上面放一个TButton。
F) 然后把这段代码放在TButton的点击事件中:
Form1->Layout1->Position->X = 0;
Form1->ChartTest->Position->Y = 0;
Form1->ChartTest->Position->X = 0;
TLineSeries *series1 = new TLineSeries(Form1);
TLineSeries *series2 = new TLineSeries(Form1);
TLineSeries *series3 = new TLineSeries(Form1);
TLineSeries *series4 = new TLineSeries(Form1);
series1->Color = claBlue;
series2->Color = claRed;
series3->Color = claBlueviolet;
series4->Color = claAqua;
double x, y;
for (int i = 0; i < 1000; i++) {
x = i;
y = Random(5000);
series1->AddXY(x,y);
y = Random(5000);
series2->AddXY(x,y);
y = Random(5000);
series3->AddXY(x,y);
y = Random(5000);
series4->AddXY(x,y);
}
Form1->ChartTest->AddSeries(series1);
Form1->ChartTest->AddSeries(series2);
Form1->ChartTest->AddSeries(series3);
Form1->ChartTest->AddSeries(series4);
G) 现在,将您的 iOS 设备连接到您的 mac 并打开 Xcode 控制台,过滤“Project1”上的控制台输出(如果您将其命名为)。然后运行应用程序并向后/向前和/或向上/向下滚动(如果您想来回也可以更改方向)。你会看到大量的断言。最终(这种骚扰大约需要 2-3 分钟才能使其崩溃)它会消耗足够的内存而导致崩溃。
我认为内存泄漏最有可能在 TeeChart 中,也许在 TScrollBox 中?
谢谢, 罗斯
【问题讨论】:
-
我没有在 FMX 中编码,但我看不到
delete series1;... 所以除非TChart自行发布它或不制作自己的副本(我怀疑)它会记忆泄漏...但是如果您在滚动事件中得到它,崩溃会更有意义...所以检查被遗忘的删除...您可以发布 MCVE 吗? (cpp,hpp,dfm) 的最小应用程序像这样崩溃...您可能忽略了一些琐碎的事情(由于记忆力,代码作者很常见,大脑会看到它记住的内容应该在那里而不是真实的内容) -
感谢 Spektre。我把我的测试项目(Project1)放在这里:relayman.org/temp/_tmpp
-
嗯,我没有看到任何可疑的 appart 那些丢失的删除,所以它可能是一个编译器/框架错误。如果情况发生变化,请尝试添加丢失的删除...
-
我添加了
delete行,它没有任何区别。我也尝试了TVertScrollBox,但结果相同(内存崩溃)。它是 TScrollBox 的后代,所以这并不奇怪。我正在想办法在不使用TScrollBox的情况下获得滚动效果。 -
我通过去掉
TChart并在滚动框上放了一堆TRectangles进行了测试。我可以滚动直到我的手指脱落,没有问题。所以,我在想TScrollBox和TChart之间一定会发生一些互动吗?在我的原始应用程序(不是上面链接的测试应用程序)中,我刚刚完全摆脱了TScrollBox,内存崩溃问题就消失了。现在我正在编写自定义代码以在不使用滚动框的情况下上下滚动我的TLaytout....
标签: firemonkey c++builder