最小的CoreML预测泄漏内存

时间:2019-02-11 15:41:52

标签: c++ objective-c macos machine-learning coreml

使用CoreML预测时出现内存泄漏(应用程序内存正在增加)。 我找不到任何可能丢失的文档或示例。 在我的真实项目中,我禁用了ARC,但是这里没有(因此,编译器不允许我手动释放任何内容,所以我想我尝试过的那些东西不需要它)

我已将其缩小为a minimal case available on github。但这只是其中的99%(存储库仅包含模型和其他项目资产,并且进行了更多的错误检查-没有错误,预测运行良好,但是由于stackoverflow而减少了)

#import <Cocoa/Cocoa.h>
#import  "SsdMobilenet.h"
#include <string>
#include <iostream>

uint8_t ImageBytes[300*300*4];

CVPixelBufferRef MakePixelBuffer(size_t Width,size_t Height)
{
    auto* Pixels = ImageBytes;
    auto BytesPerRow = Width * 4;
    CVPixelBufferRef PixelBuffer = nullptr;
    auto Result = CVPixelBufferCreateWithBytes( nullptr, Width, Height, kCVPixelFormatType_32BGRA, Pixels, BytesPerRow, nullptr, nullptr, nullptr, &PixelBuffer );
    return PixelBuffer;
}

int main(int argc, const char * argv[])
{
    auto* Pixels = MakePixelBuffer(300,300);

    SsdMobilenet* ssd = nullptr;

    for ( auto i=0; i<10000;    i++ )
    {
        if ( !ssd )
        {
            ssd = [[SsdMobilenet alloc] init];
        }
        auto* Output = [ssd predictionFromPreprocessor__sub__0:Pixels error:nullptr];
    }
    return 0;
}

是否应该清除,释放,释放和释放内存? 我尝试释放ssd并在每次迭代时都重新创建它,但这无济于事。

在HighSierra 10.13.6上,xcode 10.1(10B61)。

在此2011 imac(无金属,CPU执行力)和2013 Retina MBP(在GPU上运行)以及其他型号(不仅是SSDMobileNet)上发生泄漏。

编辑1:使用Generations / Snapshots查看乐器,确实看起来是输出泄漏,但是我不能deallocrelease,所以也许我需要做些其他事情释放结果? <non-object>是在CoreML内部apply_convulution_layer()调用内的所有分配。 Instruments Generations

1 个答案:

答案 0 :(得分:0)

由于@ Matthijs-Hollemans在禁用ARC的情况下使用NSAutoReleasePool,因此不会泄漏。 (我也可以自动释放SSD,但是这种特殊的组合可以使预先分配的SSD保持持久状态。)

由于NSAutoReleasePool不可用,我没有用于ARC / AutoReferenceCounting构建的解决方案。

int main(int argc, const char * argv[])
{
    auto* Pixels = MakePixelBuffer(300,300);

    SsdMobilenet* ssd = [[SsdMobilenet alloc] init];
    //SsdMobilenet* ssd = nullptr;

    for ( auto i=0; i<10000;    i++ )
    {
        NSAutoreleasePool* pool= [[NSAutoreleasePool alloc]init];
        if ( !ssd )
        {
            ssd = [[SsdMobilenet alloc] init];
        }
        auto* Output = [ssd predictionFromPreprocessor__sub__0:Pixels error:nullptr];
        //[Output release];
        //[ssd release];
        //ssd = nullptr;
        [pool drain];
    }
    return 0;
}