1

我在计算汉明距离的命令行 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 正在终止进程。

任何帮助表示赞赏。

4

1 回答 1

1

这可能是你的[hashStr1 UTF8String]电话,这将分配一个char*缓冲区,在你的自动释放上下文清理之前不会被释放,如果你在循环中调用所有这些而不返回到你的NSRunLoop. 参见示例-[NSString UTF8String] 的保证生命周期是什么?

于 2017-04-17T21:59:13.583 回答