【问题标题】:Minimal CoreML Prediction Leaking Memory最小的 CoreML 预测泄漏内存
【发布时间】:2019-07-05 03:46:19
【问题描述】:

我在使用 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它,所以也许我需要做其他事情来释放结果? &lt;non-object&gt; 是 CoreML 深处的 apply_convulution_layer() 调用中的所有分配。

【问题讨论】:

  • 尝试将循环内部放入NSAutoreleasePool
  • 添加 NSAutoreleasePool* pool= [[NSAutoreleasePool alloc]init]; 会给我编译器错误,即它在 ARC 模式下不可用...我用错了吗? (将尝试禁用 ARC...)

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


【解决方案1】:

感谢@Matthijs-Hollemans,使用 NSAutoReleasePool 并禁用 ARC,这不会泄漏。 (我也可以自动释放 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;
}

【讨论】:

  • 启用 ARC 后可以使用@autoreleasepool { ... }
猜你喜欢
  • 2021-07-25
  • 1970-01-01
  • 2012-07-16
  • 1970-01-01
  • 1970-01-01
  • 2015-03-28
  • 2013-03-10
  • 1970-01-01
相关资源
最近更新 更多