美文网首页
查看内存工具

查看内存工具

作者: Abner_XuanYuan | 来源:发表于2023-10-25 08:28 被阅读0次
    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
        }
    }
    

    相关文章

      网友评论

          本文标题:查看内存工具

          本文链接:https://www.haomeiwen.com/subject/eqgfidtx.html