【问题标题】:memory leak in strtoull() call in Hamming Distance calc汉明距离计算器中 strtoul() 调用中的内存泄漏
【发布时间】:2017-09-13 11:24:05
【问题描述】:

我在计算汉明距离的命令行 Objective-C OS X 应用程序中调用 strtoull() 超过 1 亿次。我已经从 ph_hamming_distance() 跟踪到此函数调用的 ~30 字节/调用内存泄漏。我查看了 strtoull() 的 BSD 源代码,甚至删除了我不需要的通用性,并将源代码放在我的应用程序中,但仍然存在内存泄漏。

调用代码是:

    NSArray * returnMatchedImagesFromDB(NSString * hash, NSString * asin, NSInteger action) {

        /*  Input hash, asin, action(not yet used)
         *  Calculate Hamming Distance to all records in DB
         *  Return NSArray of HammingDistanceRecords of matches within "hdCompareThreshold" of each other
         */ 
        int  hd;
        int threshold = 0;
        NSMutableArray * retArray = [[NSMutableArray alloc] init];

        threshold = hdCompareThreshold;

        // for each image in dbImageArray, compute hamming distance to all other images
        for (ImageRecord *imgRecord in dbImageArray) {
            hd = ph_hamming_distance(imgRecord.hash, hash);
            if ((threshold == -1) || (hd <= threshold)) {
                HammingDistanceRecord * hdRec = [[HammingDistanceRecord alloc] init];
                hdRec.hammingDistance = hd;
                hdRec.asin1 = asin;
                hdRec.asin2 = imgRecord.asin;
                hdRec.rank2 = imgRecord.rank;
                [retArray addObject:hdRec];
            }
        }
        return [retArray copy];
    }   // returnMatchedImagesFromDB()

int ph_hamming_distance(NSString * hashStr1,NSString * hashStr2) {

            NSUInteger hash1 = strtoull([hashStr1 UTF8String],NULL,0);
            NSUInteger hash2 = strtoull([hashStr2 UTF8String],NULL,0);
            NSUInteger x = hash1^hash2;
            const NSUInteger m1  = 0x5555555555555555ULL;
            const NSUInteger m2  = 0x3333333333333333ULL;
            const NSUInteger h01 = 0x0101010101010101ULL;
            const NSUInteger m4  = 0x0f0f0f0f0f0f0f0fULL;
            x -= (x >> 1) & m1;
            x = (x & m2) + ((x >> 2) & m2);
            x = (x + (x >> 4)) & m4;
            return (x * h01)>>56;
        }

ph_hamming_distance() 的参数始终为 base10(没有 alpha 字符)。典型的 hashStr 是 @"17609976980814024116"。我正在比较的对象数据库目前有 390K 个对象,因此所有对象与其自身的内部比较是对 strtoull() 的 3000 亿次调用。泄漏导致我的应用程序每次在 ~3500 比较时 SIGKILL -9。这是 3500*390K*2 调用/比较 = ~80 GB,这是我驱动器上的可用空间,所以我猜当交换文件填满驱动器时 OS X 正在终止进程。

任何帮助表示赞赏。

【问题讨论】:

  • 我的猜测是它不仅仅是strtoull。你能否展示你的循环正在执行对ph_hamming_distance 的调用?

标签: objective-c macos hash memory-leaks strtoull


【解决方案1】:

可能是您的 [hashStr1 UTF8String] 调用,这将分配一个 char* 缓冲区,直到您的自动释放上下文清理干净后才会释放,如果您在循环中调用所有这些,这可能是“永远不会”无需返回您的NSRunLoop。例如见What is the guaranteed lifecycle of -[NSString UTF8String]?

【讨论】:

  • 但是命令行程序没有 NSRunloop,是吗?也许我会尝试创建一个显式的 char * p1 = [hashStr1 UTF8String],将 p 发送到 strtoull(p, NULL, 0),然后执行 p = nil。这应该允许释放缓冲区吗?似乎这个问题应该被很多人发送字符串到某些 f(string) 所遇到。
  • p = nil 不会释放任何东西。看看你是否能找到一种方法来手动排空自动释放池。也许你可以在你的内部循环周围放置一个@autorelease { ... } 块?见developer.apple.com/library/content/documentation/Cocoa/…
  • @rick 这就是问题所在;命令行程序没有运行循环,而您正在调用需要运行循环或手动管理自动释放池的代码。
  • @faffaffaff 您的自动释放块建议成功了!处理 25,000 条记录后,内存大小恒定为 95MB。这实际上是我的其他命令行程序的解决方案,这些程序正在增长到巨大的足迹。谢谢!!也许我应该更多地阅读 Apple 文档,而不是将搜索限制在 StackOverflow :-) 抱歉,我没有足够的分数来支持你的建议。
猜你喜欢
  • 2019-04-23
  • 1970-01-01
  • 1970-01-01
  • 2014-09-25
  • 1970-01-01
  • 1970-01-01
  • 2016-10-31
  • 2016-06-05
  • 2022-01-16
相关资源
最近更新 更多