Điều này đã được thử nghiệm trên Xcode 11 trong Mojave 10.4.6 vào ngày 07/01/2019.
Tất cả các câu trả lời trước đó đều trả về kết quả không chính xác .
Đây là cách nhận được giá trị mong đợi được viết bởi Quinn của Apple “The Eskimo!”.
Điều này sử dụng phys_footprint
var from Darwin > Mach > task_info
và khớp chặt chẽ với giá trị trong bộ nhớ trong trình điều hướng Gỡ lỗi của Xcode .
Giá trị trả về tính bằng byte.
https://forums.developer.apple.com/thread/105088#357415
Mã gốc sau đây.
func memoryFootprint() -> mach_vm_size_t? {
// The `TASK_VM_INFO_COUNT` and `TASK_VM_INFO_REV1_COUNT` macros are too
// complex for the Swift C importer, so we have to define them ourselves.
let TASK_VM_INFO_COUNT = mach_msg_type_number_t(MemoryLayout<task_vm_info_data_t>.size / MemoryLayout<integer_t>.size)
let TASK_VM_INFO_REV1_COUNT = mach_msg_type_number_t(MemoryLayout.offset(of: \task_vm_info_data_t.min_address)! / MemoryLayout<integer_t>.size)
var info = task_vm_info_data_t()
var count = TASK_VM_INFO_COUNT
let kr = withUnsafeMutablePointer(to: &info) { infoPtr in
infoPtr.withMemoryRebound(to: integer_t.self, capacity: Int(count)) { intPtr in
task_info(mach_task_self_, task_flavor_t(TASK_VM_INFO), intPtr, &count)
}
}
guard
kr == KERN_SUCCESS,
count >= TASK_VM_INFO_REV1_COUNT
else { return nil }
return info.phys_footprint
}
Sửa đổi một chút điều này để tạo một tập hợp các phương thức Swift ở cấp độ lớp cho phép dễ dàng trả về các byte thực tế và đầu ra được định dạng theo MB để hiển thị. Tôi sử dụng phần mềm này như một phần của bộ UITest tự động để ghi lại bộ nhớ được sử dụng trước và sau nhiều lần lặp lại của cùng một thử nghiệm để xem liệu chúng tôi có bất kỳ rò rỉ hoặc phân bổ tiềm năng nào mà chúng tôi cần xem xét hay không.
// Created by Alex Zavatone on 8/1/19.
//
class Memory: NSObject {
// From Quinn the Eskimo at Apple.
// https://forums.developer.apple.com/thread/105088#357415
class func memoryFootprint() -> Float? {
// The `TASK_VM_INFO_COUNT` and `TASK_VM_INFO_REV1_COUNT` macros are too
// complex for the Swift C importer, so we have to define them ourselves.
let TASK_VM_INFO_COUNT = mach_msg_type_number_t(MemoryLayout<task_vm_info_data_t>.size / MemoryLayout<integer_t>.size)
let TASK_VM_INFO_REV1_COUNT = mach_msg_type_number_t(MemoryLayout.offset(of: \task_vm_info_data_t.min_address)! / MemoryLayout<integer_t>.size)
var info = task_vm_info_data_t()
var count = TASK_VM_INFO_COUNT
let kr = withUnsafeMutablePointer(to: &info) { infoPtr in
infoPtr.withMemoryRebound(to: integer_t.self, capacity: Int(count)) { intPtr in
task_info(mach_task_self_, task_flavor_t(TASK_VM_INFO), intPtr, &count)
}
}
guard
kr == KERN_SUCCESS,
count >= TASK_VM_INFO_REV1_COUNT
else { return nil }
let usedBytes = Float(info.phys_footprint)
return usedBytes
}
class func formattedMemoryFootprint() -> String
{
let usedBytes: UInt64? = UInt64(self.memoryFootprint() ?? 0)
let usedMB = Double(usedBytes ?? 0) / 1024 / 1024
let usedMBAsString: String = "\(usedMB)MB"
return usedMBAsString
}
}
Thưởng thức!
Lưu ý: một lập trình viên táo bạo có thể muốn thêm một trình định dạng tĩnh vào lớp để usedMBAsString
chỉ trả về 2 chữ số thập phân quan trọng.