2014-09-09 2 views
3

저는 Swift를 배우려고 노력 중이므로 그 목적을 위해 약간의 테스트 응용 프로그램을 작성했습니다. 디렉토리에있는 항목의 전체 크기를 제공하고 하위 디렉토리로 돌아가서 내용의 전체 크기를 누적합니다. 응용 프로그램은 작동하지만 메모리 사용량은 실행되는 동안 커지고 커집니다. 재귀 호출이 돌아 오면 재귀가 깊어지고 감소하면 메모리 사용량이 증가 할 것으로 예상했습니다. 그 대신에, 메모리 사용은 끊임없이 올라갑니다. 기기는 누출을 식별하지 않습니다. 나는 포함 나는 다양한 구글 결과에서 발견 한 몇 가지 팁을 시도했다 :Swift 앱에서 메모리 누수를 찾을 수 없습니다.

다시 사용하여 다시 사용하지 않는 기본 NSFileManager를을 기본 NSFileManager를 을하지만, 문자열 보간

을 피하고 각 재귀 호출 을위한 새로운 하나를 만들어

아무런 차이가없는 것 같습니다. 나는 그들의 참조 횟수가 0에 도달했을 때 Swift가 객체를 정리할 것이라고 생각했다. 당신은 아마도 재귀 호출 주위에, 루프에 autoreleasepool를 추가 할 필요가

import Foundation 

func sizeOfContents(path: String) -> UInt64 
{ 
    let subManager = NSFileManager() 
    var totalSize: UInt64 = 0; 
    var isDir: ObjCBool = false 
    if subManager.fileExistsAtPath(path, isDirectory: &isDir) 
    { 
     if !isDir.boolValue 
     { 
      var error: NSError? = nil 
      let attributes: NSDictionary? = subManager.attributesOfItemAtPath(path, error: &error) 
      let size: UInt64? = attributes?.fileSize() 
      totalSize += size! 
     } 
     else 
     { 
      var error: NSError? = nil 
      if let subContents = subManager.contentsOfDirectoryAtPath(path, error: &error) 
      { 
       for subItem in subContents 
       { 
        var subName = subItem as String 
        subName = path + "/" + subName 
        totalSize += sizeOfContents(subName) 
       } 


      } 
     } 
    } 

    return totalSize 
} 

let manager = NSFileManager.defaultManager() 
var rootPath = "/Applications/" 
if let contents = manager.contentsOfDirectoryAtPath(rootPath, error: nil) 
{ 
    for item in contents 
    { 
     let itemName = item as String 
     var isDir: ObjCBool = false 
     print("item: " + (rootPath + itemName)) 
     if manager.fileExistsAtPath(rootPath + itemName, isDirectory: &isDir) 
     { 
      if !isDir.boolValue 
      { 
       var error: NSError? = nil 
       let attributes: NSDictionary? = manager.attributesOfItemAtPath(rootPath + itemName, error: &error) 
       let size: UInt64? = attributes?.fileSize() 
       println("\t\(size!)") 
      } 
      else 
      { 
       if(itemName != "Volumes") 
       { 
        let size = sizeOfContents(rootPath + itemName) 
        println("\t\(size)") 
       } 
      } 
     } 
    } 
} 

답변

2

:

은 현재 상태에서의 전체 코드입니다. 꽉 루프이므로 유휴 루프는 임시 메모리 할당을 해제하지 않습니다.

예 : 그것을했다

... 
autoreleasepool { 
    totalSize += sizeOfContents(subName) 
} 
... 
+0

. 이제 autoreleasepool을 읽어야합니다. 내가 60GB를 초과하기 전에 앱이 "/"에서 시작하여 6.4MB를 초과하지 않으며 훨씬 빨라졌습니다. SWIF (Swift Programming Language) 책에서 언급 한 적은 없지만 WWDC 세션에서이 책에 대해 뭔가를 발견했습니다 (인스트루먼트로 앱 개선하기). 고마워요! – aranha

관련 문제