2017-04-17 60 views
1

我在我的命令行調用strtoull()超過1億次Objective-C OS X應用程序計算海明距離。我從ph_hamming_distance()函數調用了一個〜30字節/調用內存泄漏。我已經看過BSD源代碼strtoull(),甚至砍掉了我不需要的一般性,並將源代碼放入應用程序中,但仍然存在內存泄漏。在海明()調用內存泄漏海明距離計算

調用代碼是:

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(沒有阿爾法字符)。典型的hashStr是@「17609976980814024116」。我正在比較的對象數據庫目前是390K對象,因此所有對象的內部比較是對strtoull()的300億次調用。泄漏導致我的應用程序SIGKILL -9在每次3500比較。這是3500 * 390K * 2調用/比較=〜80 GB這是我的驅動器上的自由空間,所以我猜OS X在交換文件填滿驅動器時正在終止進程。

任何幫助表示讚賞。

+1

我的猜測是它比'strtoull'更多。你可以顯示你的循環執行'ph_hamming_distance'的調用嗎? – Alden

回答

1

這可能是你的[hashStr1 UTF8String]呼叫,這將分配一個char*緩衝區將不會釋放,直到你的自動釋放背景下清理,這可能是「從不」,如果你調用所有這一切都在一個循環,而不返回回達到您的NSRunLoop。看例如What is the guaranteed lifecycle of -[NSString UTF8String]?

+0

但是一個命令行程序沒有NSRunloop,是嗎?也許我會嘗試創建一個顯式的char * p1 = [hashStr1 UTF8String],將p發送給strtoull(p,NULL,0),然後執行p = nil。應該允許釋放緩衝區嗎?似乎這個問題應該已經被很多人發送字符串給一些f(字符串)。 – rick

+1

p =零不會釋放任何東西。看看你是否能找到一種方法來手動排除autoreleasepool。也許你可以在你的內部循環中放一個'@autorelease {...}'塊?見https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html – faffaffaff

+1

@rick這就是問題;一個命令行程序將不會有runloop,並且您正在調用需要runloop或手動管理autorelease池的代碼。 – bbum