最小的 CoreML 预测泄漏内存

Minimal CoreML Prediction Leaking Memory

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

我已将其减少到 a minimal case available on github。但这是其中的 99%(存储库只有模型和额外的项目资产,以及更多的错误检查 - 没有错误,预测运行良好,但由于 Whosebug 而减少)

#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() 调用中的所有分配。

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

我没有 ARC/AutoReferenceCounting 版本的解决方案,因为 NSAutoReleasePool 不可用。

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;
}