iOS上出现内存崩溃,但内存消耗为20MB

时间:2015-01-26 11:31:26

标签: ios memory

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

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

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

但是,当我尝试分析问题的根源时,我甚至无法检测到高内存消耗,更不用说搜索问题的根源了。我已经分析了仪器中活动监视器中使用的物理内存,我的app和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;
}

2 个答案:

答案 0 :(得分:4)

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

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

示例:

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

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

调试减少循环次数,这样就不会崩溃,然后使用Heapshot:

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

如何使用“快照”查找内存褶皱,请参阅:bbum blog

基本上,该方法是运行Instruments分配工具,获取快照,运行代码的迭代并重复另外3到4次快照。这将指示在迭代期间分配但未释放的内存。

要弄清楚披露的结果,以查看个别分配。

如果您需要查看对象使用仪器的保留,释放和自动释放的位置:

在仪器中运行,在分配中设置“记录参考计数”(对于Xcode 5及更低版本,您必须停止记录以设置选项)。导致应用程序运行,停止录制,向下钻取,您将能够看到所有保留,发布和自动释放的位置。

答案 1 :(得分:0)

问题是有一个CIImage在自动释放池之外和渲染方法之外被解除引用,我已经在问题中发布了。

作为参数传递的是targetImage参数。所以现在我在方法调用之外添加了另一个自动释放池,它修复了我所有的内存问题。

对于我来说,这仍然是一个谜,但为什么那些未发布的CIImage分配并没有体现在内存监视器和其他工具中使用的内存量上。

另外,我不明白为什么坠毁只会偶尔发生。