ios - iOS 内存不足崩溃,但内存消耗为 20MB

标签 ios memory

我在 iPhone 6 和 5s 上的 iOS 应用程序都遇到了内存不足崩溃的问题。我确定内存是问题所在,因为我收到内存警告以及崩溃日志。

在应用程序中,我进行了视频处理,并在 10 秒内为一个后处理步骤处理了大约 400 张图像。每个框架的资源都在自动释放池中正确释放。崩溃发生在随机重复之后。

我在那 10 秒内分配了大量内存(总共几百 MB),但由于自定义自动释放池,内存会在每次处理图像后释放。

但是,当我尝试剖析问题的根源时,我什至无法检测到高内存消耗,更不用说搜索问题的根源了。我已经在 Instruments 的事件监视器中分析了使用的物理内存,我的应用程序和 mediaserverd 在任何给定时刻都不会消耗超过 30 MB。

当我的应用程序在峰值时仅使用 30MB 内存时,为什么会发生内存崩溃?如何正确测量和调试内存消耗?

非常感谢任何指点!

这是运行时内存报告的屏幕截图: Memory report

这是崩溃日志:

Incident Identifier: 2B5E9345-964D-4F6E-87D2-5517F0C22531
CrashReporter Key:   2033c0b344ea7cbf4f153cd862d1e7b68969b42e
Hardware Model:      iPhone6,2
OS Version:          iPhone OS 8.1.1 (12B435)
Kernel Version:      Darwin Kernel Version 14.0.0: Mon Nov  3 22:23:57 PST 2014; root:xnu-2783.3.22~1/RELEASE_ARM64_S5L8960X
Date:                2015-01-26 12:04:35 +0100
Time since snapshot: 672 ms

Free pages:                              2515
Active pages:                            23951
Inactive pages:                          11816
Speculative pages:                       643
Throttled pages:                         0
Purgeable pages:                         0
Wired pages:                             133367
File-backed pages:                       10813
Anonymous pages:                         25597
Compressions:                            8823352
Decompressions:                          752051
Compressor Size:                         83913
Uncompressed Pages in Compressor:        155021
Page Size:                               16384
Largest process:   RedGlam

Processes
Name       |            <UUID>                |     CPU Time|     rpages|       purgeable| recent_max| lifetime_max| fds |  [reason]         | (state)

timed <6fa98ab7f5de312b9bfed47e04e3a43e>         0.075         240                0          +5           701   50   [vm-pageshortage]   (daemon) (idle)
calaccessd <0a7ad7bbfb523bfdbae43aa6f21279f6>         0.134         462                0         +47          1279   50   [vm-pageshortage]   (daemon) (idle)
MobileGestaltHel <19968f31a89230a6b66e51ad668f0921>         0.028         163                0           -           522   50   [vm-pageshortage]   (daemon) (idle)
awdd <58036e1703903ee798a8803de204c300>         0.123         405                0           -          1076   50   [vm-pageshortage]   (daemon) (idle)
WirelessRadioMan <c4181e6d863133e8aa0c95e77a7bb206>         0.051         293                0           -           787   50   [vm-pageshortage]   (daemon) (idle)
notification_pro <b143453e80393938a7ba23a0181dc52c>         0.158         148                0           -           451   50   [vm-pageshortage]   (daemon)
com.apple.dt.ins <c2263ead004b339f9fe48bbdf95286c9>        30.091         255                0           -           787   50   [vm-pageshortage]   (daemon)
debugserver <f00a5e2ac8f73e7e893c711d88c344a6>        24.790         208                0           -           681   50   [vm-pageshortage]   (daemon)
MobileMail <4b48abd990e93dbea47db1cbf328da9e>         6.030        1518                0           -          4299   50                       (resume) (continuous)
lsd <f554bd07b90a3cfc9d9ef9f8e234833c>         1.443         333                0           -           859   50                       (daemon)
tccd <f2878273872231afa1a6e0af2dcb73a6>         0.619         278                0           -           861   50                       (daemon)
MYAPP <417ba797cf3e39df82d79baf41050692>       389.444      105870                0           -         13874   50                       (audio) (frontmost) (resume)
ptpd <a06176d3eefe3e3c8549bb4f6d340658>         1.913         817                0           -          2043   50                       (daemon)
BTServer <2d0fc0974c073a0aafc9954110080950>        16.246         572                0           -          1859   50                       (daemon)
wifid <43e56e539a6a3114bf4cd7646c8dd90e>       149.958         561                0           -          1564   50                       (daemon)
discoveryd <68f73878299336d7872b0ae9ce3f7f08>       179.311         585                0           -          1220  100                       (daemon)
locationd <5b826e2c09c23eaaa2acc2472269cb30>      4461.461        2209                0           -          5025   50                       (daemon)
lockdownd <3a0b3375ad6e391da37a1f79f46843b0>        39.278         364                0           -          1345   50                       (daemon)
syslogd <05f6b5e5512938a892bac5af23ab1c08>       127.902         240                0           -           818   50                       (daemon)
powerd <2b4ae8758a5b3b709a97c452ec08923b>        56.978         310                0           -           579   50                       (daemon)
imagent <d5e037ad2173362d8a6077788b2d7074>        13.323         529                0           -          1354   50                       (daemon)
identityservices <9d4b00e3c6003685ac8697c59f4e4d38>        16.729         687                0           -          1794   50                       (daemon)
vmd <c3b3270d187f3dcaa843ba73f01ff8cb>         0.482         595                0           -          2598   50                       (daemon)
cfprefsd <4325eab208063b998046460a4c2ee484>        32.394         449                0           -           742   50                       (daemon)
iaptransportd <4bf77076d69630e389ba64229c526723>        20.807         364                0           -           971   50                       (daemon)
apsd <bb925404cb1137b09b85671a8d2c7656>        62.713         738                0           -          1892   50                       (daemon)
networkd <fa2acedf0b0035269d66a72e28c3a95a>       307.451         716                0           -          1585   50                       (daemon)
sharingd <1ed17c64831f32ea9cbb47e48c4d222c>        29.442         944                0           -          2298   50                       (daemon)
dataaccessd <33bcaea3bc473f128685f4df14a115eb>        13.535         729                0           -          2230   50                       (daemon)
SCHelper <779250b8a48638958a5922f6ae1066fa>        10.160         134                0           -           324   50                       (daemon)
searchd <e5c5e5675c0935eaab5feb15ebc0b934>         5.392         888                0           -          2986   50                       (daemon)
mediaserverd <a0354e528bc431958df0d50830bead36>      1080.882       91747                0           -         21944  200                       (daemon)
syslog_relay <087c67d0371b324fb6df48442016ec90>         6.746         114                0           -           237   50                       (daemon)
SpringBoard <96f929dd23123d8bbc9ba2a0bb48bde1>      1108.457        8031                0           -         17537   50
backboardd <e263837653b434f1880f9d37b3926998>      7219.545        7865                0           -          4676   50                       (daemon)
UserEventAgent <f5a211b9c88e3fa481f2bd1ee1f5a921>      1084.316        1000                0           -          2811  100                       (daemon)
fseventsd <16c9b62bb28c388ca10d54dbff18c4f8>        20.426         496                0           -           843   50                       (daemon)
configd <ed40fcde35ae337ab3b70073199564b1>       117.075         537                0           -          1463   50                       (daemon)
fairplayd.H2 <cae337642f6d396b82ac54e72bc0e0a4>         6.550         151                0           -          1433   50                       (daemon)
wirelessproxd <ab1fa7e43a7c3f9393533404c2cc80b8>         1.814         264                0           -           986   50                       (daemon)
assertiond <10ec04add18f3ecd8a8efbb1cc4e2bd6>        18.292         325                0           -          1045   50                       (daemon)
aggregated <281958649a3130aab6ecb1aa47f0a6c1>      2273.629        1367                0           -          2822   50                       (daemon)
distnoted <cb5e76091dc53ceeaf65290f8e197a89>         4.937         207                0           -           335   50                       (daemon)
discoveryd_helpe <492c39ae2d643adca0ed971675c77406>         0.120         156                0           -           752   50                       (daemon)
filecoordination <5ec159db1afe3317878b8ab794e2d7d1>         1.259         308                0           -           941   50                       (daemon)
DTMobileIS <2fdc94aa5069338e815fbe3a13e3d95c>       551.592        2538                0           -         36844   50                       (daemon)
gputoolsd <97e54c888a9a3978a85fd965a71e7669>         9.503        1031                0           -          2910   50                       (daemon)
CommCenter <33412ab229c738c8860c70803fed173b>       787.039        1465                0           -          4737   50                       (daemon)
notifyd <5fa8fd5e44c83f64be1475b882b16c82>       142.939         384                0           -           441   50                       (daemon)
ReportCrash <e946799f25f833fd9b37a6a1c7b1993c>         0.039         166                0           -           551   50                       (daemon)

**End**

这是我正在使用的一种效果的代码(renderAnimation2DOverFace 不分配任何内存):

- (CIImage *) render:(CIImage*)targetImage imageContext:(CIContext*) imageContext
      facialFeatures:(NSArray*)facialFeatures currentFrameInd:(int)frameInd
{
    if ( !facialFeatures ) return targetImage;

    @autoreleasepool {
        UIImage *editingImage = [[UIImage alloc] initWithCIImage:targetImage];
        UIGraphicsBeginImageContextWithOptions(editingImage.size, NO, 1.0);

        [editingImage drawInRect:CGRectMake( 0, 0, editingImage.size.width, editingImage.size.height)];

        for ( ArtechFacialFeature *facialFeature in facialFeatures ) {
            [self renderAnimation2DOverFace:facialFeature.bounds
                                            currentFrameInd:frameInd];
        }

        UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();

        targetImage = [targetImage initWithCGImage:resultImage.CGImage options:nil];

        editingImage = nil;
        resultImage = nil;
    }

    return targetImage;
}

这是另一个视频效果例程:

- (CIImage *) render:(CIImage*)targetImage imageContext:(CIContext*) imageContext
    facialFeatures:(NSArray*)facialFeatures currentFrameInd:(int)frameInd
{
    if ( !facialFeatures ) return targetImage;

    @autoreleasepool {
        CGImageRef inputImage = [imageContext createCGImage:targetImage fromRect:[targetImage extent]];

        GPUImagePicture *sourcePicture = [[GPUImagePicture alloc] initWithCGImage:inputImage];
        GPUImageOutput *currentOutput = [self createFilterChain:sourcePicture facialFeatures:facialFeatures
            imageExtent:targetImage.extent];

        [currentOutput useNextFrameForImageCapture];
        [sourcePicture processImage];

        UIImage *currentFilteredVideoFrame = [currentOutput imageFromCurrentFramebuffer];

        targetImage = [targetImage initWithCGImage:currentFilteredVideoFrame.CGImage];

        currentFilteredVideoFrame = nil;

        [sourcePicture removeAllTargets];
        sourcePicture = nil;

        [currentOutput removeOutputFramebuffer];
        currentOutput = nil;

        CFRelease( inputImage );

        [[GPUImageContext sharedFramebufferCache] purgeAllUnassignedFramebuffers];
    }

    return targetImage;
}

最佳答案

在循环中执行使用自动释放内存的处理时,您需要在循环内放置一个自动释放池。请注意,许多 Cocoa 和 Foundation 方法使用自动释放的内存。

问题是每个操作都在保留和自动释放内存,但直到当前自动释放池耗尽后内存才真正释放,通常在运行循环中并且由于紧密循环而未被调用。

例子:

for (...) {
    @autoreleasepool {
        perform work
    }
}

您可以在操作的较小部分周围放置一个自动释放池。

要进行调试,请减少循环次数以免崩溃,然后使用 Heapshot:

使用仪器检查由于保留但未泄漏的内存而导致的泄漏和内存丢失。后者是仍指向的未使用内存。在 Instruments 的分配工具中使用标记生成(Heapshot)。

有关如何使用 Heapshot 查找内存泄漏的信息,请参阅:bbum blog

基本上,该方法是运行 Instruments 分配工具,进行一次堆快照,运行一次代码迭代,然后再次进行一次堆快照,重复 3 或 4 次。这将指示在迭代期间分配和未释放的内存。

要弄清楚结果,请查看个人分配。

如果您需要查看某个对象的保留、释放和自动释放发生在何处,请使用工具:

在 instruments 中运行,在 Allocations 中设置“Record reference counts”(对于 Xcode 5 及更低版本,您必须停止记录才能设置该选项)。让应用程序运行、停止记录、向下钻取,您将能够看到所有保留、释放和自动释放发生的位置。

关于ios - iOS 内存不足崩溃,但内存消耗为 20MB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28149261/

相关文章:

c - 错误 : "pointer being freed was not allocated" in c

ios - 同时选择另一个表格 View 单元格时如何取消选择表格 View 单元格?

ios - 如何创建核心数据 NSManagedObject 的独立实例 - 未托管

ios - 增强现实,根据设备移动移动 3d 模型

c++ - 将指向堆栈变量的指针传递给 realloc() 是否有效?

n 秒内的 Docker 统计信息

objective-c - ARC 中的强大属性 - Objective C

ios - 使用通用协议(protocol)过滤 subview 数组

Windows 保护模式 - 内存

c++ - 如何调试奇怪的内存泄漏 (C++)