查看内存工具
2023-10-25 本文已影响0人
Abner_XuanYuan
import Foundation
public enum MemAlign : Int {
case one = 1, two = 2, four = 4, eight = 8
}
private let _EMPTY_PTR = UnsafeRawPointer(bitPattern: 0x1)!
/// 辅助查看内存的小工具类
public struct Mems<T> {
private static func _memStr(_ ptr: UnsafeRawPointer,
_ size: Int,
_ aligment: Int) ->String {
if ptr == _EMPTY_PTR { return "" }
var rawPtr = ptr
var string = ""
let fmt = "0x%0\(aligment << 1)lx"
let count = size / aligment
for i in 0..<count {
if i > 0 {
string.append(" ")
rawPtr += aligment
}
let value: CVarArg
switch aligment {
case MemAlign.eight.rawValue:
value = rawPtr.load(as: UInt64.self)
case MemAlign.four.rawValue:
value = rawPtr.load(as: UInt32.self)
case MemAlign.two.rawValue:
value = rawPtr.load(as: UInt16.self)
default:
value = rawPtr.load(as: UInt8.self)
}
string.append(String(format: fmt, value))
}
return string
}
private static func _memBytes(_ ptr: UnsafeRawPointer,
_ size: Int) -> [UInt8] {
var arr: [UInt8] = []
if ptr == _EMPTY_PTR { return arr }
for i in 0..<size {
arr.append((ptr + i).load(as: UInt8.self))
}
return arr
}
/// 获得变量的内存数据(字节数组格式)
public static func memBytes(ofVal v: inout T) -> [UInt8] {
return _memBytes(ptr(ofVal: &v), MemoryLayout.stride(ofValue: v))
}
/// 获得引用所指向的内存数据(字节数组格式)
public static func memBytes(ofRef v: T) -> [UInt8] {
let p = ptr(ofRef: v)
return _memBytes(p, malloc_size(p))
}
/// 获得变量的内存数据(字符串格式)
///
/// - Parameter alignment: 决定了多少个字节为一组
public static func memStr(ofVal v: inout T, alignment: MemAlign? = nil) -> String {
let p = ptr(ofVal: &v)
return _memStr(p, MemoryLayout.stride(ofValue: v),
alignment != nil ? alignment!.rawValue : MemoryLayout.alignment(ofValue: v))
}
/// 获得引用所指向的内存数据(字符串格式)
///
/// - Parameter alignment: 决定了多少个字节为一组
public static func memStr(ofRef v: T, alignment: MemAlign? = nil) -> String {
let p = ptr(ofRef: v)
return _memStr(p, malloc_size(p),
alignment != nil ? alignment!.rawValue : MemoryLayout.alignment(ofValue: v))
}
/// 获得变量的内存地址
public static func ptr(ofVal v: inout T) -> UnsafeRawPointer {
return MemoryLayout.size(ofValue: v) == 0 ? _EMPTY_PTR : withUnsafePointer(to: &v) {
UnsafeRawPointer($0)
}
}
/// 获得引用所指向内存的地址
public static func ptr(ofRef v: T) -> UnsafeRawPointer {
if v is Array<Any>
|| Swift.type(of: v) is AnyClass
|| v is AnyClass {
return UnsafeRawPointer(bitPattern: unsafeBitCast(v, to: UInt.self))!
} else if v is String {
var mstr = v as! String
if mstr.memType() != .heap {
return _EMPTY_PTR
}
return UnsafeRawPointer(bitPattern: unsafeBitCast(v, to: (UInt, UInt).self).1)!
} else {
return _EMPTY_PTR
}
}
/// 获得变量所占用的内存大小
public static func size(ofVal v: inout T) -> Int {
return MemoryLayout.size(ofValue: v) > 0 ? MemoryLayout.stride(ofValue: v) : 0
}
/// 获得引用所指向内存的大小
public static func size(ofRef v: T) -> Int {
return malloc_size(ptr(ofRef: v))
}
}
public enum StringMemType : UInt8 {
/// TEXT段(常量区)
case text = 0xd0
/// taggerPointer
case tagPtr = 0xe0
/// 堆空间
case heap = 0xf0
/// 未知
case unknow = 0xff
}
extension String {
mutating public func memType() -> StringMemType {
let ptr = Mems.ptr(ofVal: &self)
return StringMemType(rawValue: (ptr + 15).load(as: UInt8.self) & 0xf0)
?? StringMemType(rawValue: (ptr + 7).load(as: UInt8.self) & 0xf0)
?? .unknow
}
}