প্রোগ্রামে আইফোনে মেমরির ব্যবহার পুনরুদ্ধার করুন


101

আমি আমার আইফোন অ্যাপ্লিকেশনটি যে কোনও সময়, প্রোগ্রামগতভাবে ব্যবহার করছি তার পরিমাণ পুনরুদ্ধার করার চেষ্টা করছি। হ্যাঁ আমি অবজেক্টএলোক / লিকস সম্পর্কে সচেতন। আমি সেগুলিতে আগ্রহী নই, কেবলমাত্র কিছু কোড লিখতে এবং ব্যবহারযোগ্য বাইটের পরিমাণ পাওয়া এবং এনএসএলগের মাধ্যমে এটি রিপোর্ট করা সম্ভব কিনা তা জানতে হবে।

ধন্যবাদ।


ম্যান, আমি ইতিমধ্যে মেমরির ব্যবহার সফলভাবে পুনরুদ্ধার করেছি; তবে আপনি কি আমার সম্পর্কিত প্রশ্নের উত্তর দিতে সহায়তা করতে পারেন? stackoverflow.com/questions/47071265/…
জান্নাত

: এখানে কিভাবে সঠিক উত্তর পেতে এর stackoverflow.com/a/57315975/1058199
অ্যালেক্স Zavatone

উত্তর:


134

আপনার অ্যাপ্লিকেশনটি ব্যবহার করছে এমন মেমরির আসল বাইট পেতে, আপনি নীচের উদাহরণের মতো কিছু করতে পারেন। তবে আপনাকে বিভিন্ন প্রোফাইলিং সরঞ্জামগুলির সাথে সত্যই পরিচিত হওয়া উচিত এবং পাশাপাশি সেগুলি আপনাকে সর্বোপরি ব্যবহারের আরও অনেক ভাল চিত্র দেওয়ার জন্য ডিজাইন করা হয়েছে।

#import <mach/mach.h>

// ...

void report_memory(void) {
  struct task_basic_info info;
  mach_msg_type_number_t size = TASK_BASIC_INFO_COUNT;
  kern_return_t kerr = task_info(mach_task_self(),
                                 TASK_BASIC_INFO,
                                 (task_info_t)&info,
                                 &size);
  if( kerr == KERN_SUCCESS ) {
    NSLog(@"Memory in use (in bytes): %lu", info.resident_size);
    NSLog(@"Memory in use (in MiB): %f", ((CGFloat)info.resident_size / 1048576));
  } else {
    NSLog(@"Error with task_info(): %s", mach_error_string(kerr));
  }
}

স্ট্রাকচার ইনফো. ভার্চুয়াল_সাইজে একটি ক্ষেত্র রয়েছে যা আপনাকে উপলব্ধ ভার্চুয়াল মেমরির সংখ্যা (বা কোনও ইভেন্টে সম্ভাব্য ভার্চুয়াল মেমরি হিসাবে আপনার অ্যাপ্লিকেশনটিতে বরাদ্দ মেমরি) দেবে will পিজিবি কোডটি যে লিঙ্কটির সাথে লিঙ্ক করে তা আপনাকে ডিভাইসে উপলব্ধ মেমরির পরিমাণ এবং এটি কী ধরণের মেমরি দেয়।


4
ধন্যবাদ, ঠিক আমি যা খুঁজছিলাম এই পদ্ধতির অ্যাপ স্টোরটি কি নিরাপদ?
বুজু

3
আপনি যদি টাস্ক_বাসিক_ইনফো সিএমডি + ক্লিক করেন, তবে মনে হয় এটি এখন ব্যবহার করা উচিত এবং mach_task_basic_info দ্বারা প্রতিস্থাপন করা উচিত নয়। আমার অনুমান এই সংস্করণটি 64-বিট আর্কিটেকচারের সাথে সামঞ্জস্যপূর্ণ নয় তবে সত্যই নিশ্চিত নয়।
cprcrack

14
আমার ক্ষেত্রে, এক্সকোডে থাকা মেমরির প্রতিবেদনের তুলনায় ফেরত পরিমাণ দ্বিগুণ হয়ে গেছে। এটা কি নিশ্চিত নয়।
মোরক্রোম

1
অন্যান্য অ্যাপ্লিকেশন দ্বারা মেমরির ব্যবহার কীভাবে পাবেন?
অমিত খান্দেলওয়াল

1
@ মোরোক্রাম আপনি বুঝতে পেরেছেন কেন? দ্বিগুণ বড় চলমান সিমুলেটর এবং ডিভাইসে প্রায় 3 বার আমার প্রায় একই সমস্যা রয়েছে।
জুলিয়ান ক্রোল

31

শিরোনামগুলি TASK_BASIC_INFOবলার জন্য :

/* Don't use this, use MACH_TASK_BASIC_INFO instead */

এখানে একটি সংস্করণ ব্যবহার করে MACH_TASK_BASIC_INFO:

void report_memory(void)
{
    struct mach_task_basic_info info;
    mach_msg_type_number_t size = MACH_TASK_BASIC_INFO_COUNT;
    kern_return_t kerr = task_info(mach_task_self(),
                                   MACH_TASK_BASIC_INFO,
                                   (task_info_t)&info,
                                   &size);
    if( kerr == KERN_SUCCESS ) {
        NSLog(@"Memory in use (in bytes): %u", info.resident_size);
    } else {
        NSLog(@"Error with task_info(): %s", mach_error_string(kerr));
    }
}

এক্সকোড প্রতিবেদনের চেয়ে সিমুলেটারে কেন এখানে লগইন করা মানটি প্রায় দ্বিগুণ এবং একটি আসল ডিভাইসে তিন গুণ বেশি?
জুলিয়ান ক্রোল

1
কেন পার্থক্য জানি না। এটি একটি ভাল নতুন প্রশ্ন করতে হবে।
সংযুক্তি

1
আমি পার্থক্য খুঁজে পেয়েছি। এটি বাসিন্দার স্মৃতির কারণে লাইভ বাইটস নয়
জুলিয়ান ক্রোল

আমরা কি অন্যান্য অ্যাপ্লিকেশনগুলির মেমরি ব্যবহার পেতে পারি ?? @combinatorial
বিকাশ বনসাল

1
@ ভিকাসবাংসাল না আপনি পারবেন না।
সংযুক্তি

18

এনএসএলগ () -তে দ্রুত ফাঁস স্থিতি প্রদর্শন করতে এখানে রিপোর্ট_মেমোরি () বর্ধিত রয়েছে।

void report_memory(void) {
    static unsigned last_resident_size=0;
    static unsigned greatest = 0;
    static unsigned last_greatest = 0;

    struct task_basic_info info;
    mach_msg_type_number_t size = sizeof(info);
    kern_return_t kerr = task_info(mach_task_self(),
                               TASK_BASIC_INFO,
                               (task_info_t)&info,
                               &size);
    if( kerr == KERN_SUCCESS ) {
        int diff = (int)info.resident_size - (int)last_resident_size;
        unsigned latest = info.resident_size;
        if( latest > greatest   )   greatest = latest;  // track greatest mem usage
        int greatest_diff = greatest - last_greatest;
        int latest_greatest_diff = latest - greatest;
        NSLog(@"Mem: %10u (%10d) : %10d :   greatest: %10u (%d)", info.resident_size, diff,
          latest_greatest_diff,
          greatest, greatest_diff  );
    } else {
        NSLog(@"Error with task_info(): %s", mach_error_string(kerr));
    }
    last_resident_size = info.resident_size;
    last_greatest = greatest;
}

2
মাপ (তথ্য) এর পরিবর্তে আকারটি TASK_BASIC_INFO_COUNT হওয়া উচিত - এই কোডটি একই কোড সহ অনেক জায়গায় অনুলিপি করা হয়েছে
ম্যাক্সিম খোলিয়াভকিন

18

07/01/2019 তারিখে মোজভেভ 10.4.6 এ এক্সকোড 11 এ পরীক্ষা করা হয়েছে।

পূর্ববর্তী সমস্ত উত্তরই ভুল ফলাফল দেয়

অ্যাপলের কুইন "দ্য এস্কিমো" দ্বারা লিখিত প্রত্যাশিত মানটি কীভাবে পাবেন তা এখানে রয়েছে।

এই ব্যবহার phys_footprintথেকে Var Darwin > Mach > task_infoএবং ঘনিষ্ঠভাবে Xcode এর ডিবাগ ন্যাভিগেটর মেমরি গেজ মান সাথে মেলে

প্রত্যাশিত মানটি বাইটে হয়।

https://forums.developer.apple.com/thread/105088#357415

মূল কোডটি অনুসরণ করে।

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  
}  

সুইফট পদ্ধতিগুলির একটি শ্রেণিবদ্ধ স্তর তৈরি করতে এটি সামান্য পরিবর্তন করে প্রকৃত বাইটের সহজ ফিরতি এবং এমবিতে ফর্ম্যাট আউটপুট প্রদর্শনের জন্য অনুমতি দেয়। আমি এটি পরীক্ষা করার আগে আমাদের কোনও সম্ভাব্য ফুটো বা বরাদ্দ আছে কিনা তা দেখতে একই পরীক্ষার একাধিক পুনরাবৃত্তির আগে এবং পরে ব্যবহৃত মেমরি লগ করতে একটি স্বয়ংক্রিয় ইউআইটিস্ট স্যুটের অংশ হিসাবে এটি ব্যবহার করি।

//  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
     }
}

উপভোগ করুন!

দ্রষ্টব্য: একটি উদ্যোগী কোডার ক্লাসে একটি স্ট্যাটিক ফর্ম্যাটর যুক্ত করতে চাইতে পারে যাতে usedMBAsStringকেবল 2 টি উল্লেখযোগ্য দশমিক স্থান দেয়।


7

জেসন কোকো এর উত্তরের দ্রুত সমাধান :

func reportMemory() {
    let name = mach_task_self_
    let flavor = task_flavor_t(TASK_BASIC_INFO)
    let basicInfo = task_basic_info()
    var size: mach_msg_type_number_t = mach_msg_type_number_t(sizeofValue(basicInfo))
    let pointerOfBasicInfo = UnsafeMutablePointer<task_basic_info>.alloc(1)

    let kerr: kern_return_t = task_info(name, flavor, UnsafeMutablePointer(pointerOfBasicInfo), &size)
    let info = pointerOfBasicInfo.move()
    pointerOfBasicInfo.dealloc(1)

    if kerr == KERN_SUCCESS {
        print("Memory in use (in bytes): \(info.resident_size)")
    } else {
        print("error with task info(): \(mach_error_string(kerr))")
    }
}

যদি আমরা জানতে চাই যে আরও কিছু অ্যাপ্লিকেশনটি (স্কাইপ) কতটা র‌্যাম ব্যবহার করছে?
বিকাশ বনসাল

4

সুইফট ৩.১ (আগস্ট 8, 2017 হিসাবে)

func getMemory() {

    var taskInfo = mach_task_basic_info()
    var count = mach_msg_type_number_t(MemoryLayout<mach_task_basic_info>.size)/4
    let kerr: kern_return_t = withUnsafeMutablePointer(to: &taskInfo) {
        $0.withMemoryRebound(to: integer_t.self, capacity: 1) {
            task_info(mach_task_self_, task_flavor_t(MACH_TASK_BASIC_INFO), $0, &count)
        }
    }
    if kerr == KERN_SUCCESS {
        let usedMegabytes = taskInfo.resident_size/(1024*1024)
        print("used megabytes: \(usedMegabytes)")
    } else {
        print("Error with task_info(): " +
            (String(cString: mach_error_string(kerr), encoding: String.Encoding.ascii) ?? "unknown error"))
    }

}

1
এই কোডটি ব্যবহার করে মেমরির ব্যবহারটি ডিবাগার থেকে মেমরির ব্যবহারের x3 বার দেখায়। কেন?

1
ভাল, আমি অনুমান করি যে বাইট থেকে মেগাবাইট পেতে আপনার (1024*1024)দ্বারা বিভাজন করা উচিত , দ্বারা নয় 1000000
আইভানজয়েড

এটি এক্স 3 এর পার্থক্য করে না।
কয়েক দশক ধরে

এটি এক্সকোড ডিবাগারের মতো একটি আসল মেমরির মান দেয়, ধন্যবাদ
তাতিয়ানা_সি

2

এখানে একটি সুইফট 3 সংস্করণ রয়েছে:

func mach_task_self() -> task_t {
    return mach_task_self_
}

func getMegabytesUsed() -> Float? {
    var info = mach_task_basic_info()
    var count = mach_msg_type_number_t(MemoryLayout.size(ofValue: info) / MemoryLayout<integer_t>.size)
    let kerr = withUnsafeMutablePointer(to: &info) { infoPtr in
        return infoPtr.withMemoryRebound(to: integer_t.self, capacity: Int(count)) { (machPtr: UnsafeMutablePointer<integer_t>) in
            return task_info(
                mach_task_self(),
                task_flavor_t(MACH_TASK_BASIC_INFO),
                machPtr,
                &count
            )
        }
    }
    guard kerr == KERN_SUCCESS else {
        return nil
    }  
    return Float(info.resident_size) / (1024 * 1024)   
}

2
এই কোডটি ব্যবহার করে মেমরির ব্যবহারটি ডিবাগার থেকে মেমরির ব্যবহারের x3 বার দেখায়। কেন?

এমনকি আমার কাছে একই সমস্যাটি প্রায় তিনগুণ বেশি যা প্রোফাইলে কী দেখানো হচ্ছে?
স্যান্ডি


-2

নীচে সঠিক উত্তর:

``

float GetTotalPhysicsMemory()
{
    struct task_basic_info info;
    mach_msg_type_number_t size = sizeof(info);
    kern_return_t kr;
    kr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size);
    if (kr == KERN_SUCCESS) 
        return (float)(info.resident_size) / 1024.0 / 1024.0;
    else
        return 0;
}

``


এই "ভুল পদার্থ" মেমরি কল করার অর্থ এই ভুল মানটিই ফিরিয়ে দেয় না এর অর্থ আপনাকে আরও বেশিবার আপনার কোডটি পর্যালোচনা করা দরকার।
অ্যালেক্স জাভাটোন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.