anggaran memori maksimum aplikasi ios

152

Saya sedang mengerjakan game ios yang menargetkan minimal 3gs. Kami menggunakan aset HD untuk perangkat layar retina (iphone 4, ipod touch 4th gen).

Dari segi memori, Ipod Touch 4th gen tampaknya menjadi perangkat yang paling kendala bagi kami karena memiliki jumlah RAM yang sama (256 dibandingkan dengan iPhone 4's 512) seperti 3gs tetapi kami menggunakan aset HD di atasnya. Aplikasi yang digunakan untuk mogok ketika mencoba memuat ram 100-110mb tapi sekarang kita turun ke 70MB, kita belum pernah memuat crash.

Setelah banyak mencari-cari, sepertinya tidak ada batas resmi yang resmi jadi bagaimana kita harus mengetahui anggaran memori apa yang digunakan agar aman? Kami ingin dapat memberi para seniman anggaran yang dapat mereka gunakan tanpa kekhawatiran ingatan untuk setiap peta.

frilla
sumber
14
Tidak yakin bagaimana pertanyaan ini dapat menjadi duplikat dari sesuatu yang ditanyakan di lain waktu.
Jasper

Jawaban:

42

Saya pikir Anda telah menjawab pertanyaan Anda sendiri: cobalah untuk tidak melampaui batas 70 Mb, namun itu benar-benar tergantung pada banyak hal: versi iOS apa yang Anda gunakan (bukan SDK), berapa banyak aplikasi yang berjalan di latar belakang, memori apa yang tepat Anda menggunakan dll

Cukup hindari percikan memori instan (mis. Anda menggunakan 40 Mb RAM, dan kemudian mengalokasikan lebih dari 80 Mb untuk beberapa perhitungan pendek). Dalam hal ini iOS akan segera membunuh aplikasi Anda.

Anda juga harus mempertimbangkan pemuatan aset yang malas (hanya memuatnya saat Anda benar-benar membutuhkan dan tidak sebelumnya).

Maks
sumber
2
Hanya saja kami ingin menempatkan barang sebanyak yang kami bisa (grafik & suara). Seniman akan selalu ingin memasukkan sebanyak mungkin mereka ke dalam permainan itu sebabnya saya ingin membatasi mereka dengan anggaran. Saya kira kita hanya perlu menguji pada banyak perangkat yang berbeda dalam pengaturan yang berbeda untuk menemukan jejak memori maksimum yang wajar untuk digunakan.
frilla
2
Akankah mengalokasikan hanya 70MB (yang mungkin di bawah anggaran) kapan saja pada perangkat itu (bahkan setelah penggunaan yang berat di aplikasi yang haus memori lainnya) selalu menjamin alokasi yang berhasil, atau akankah itu berpotensi masih macet?
Steven Lu
1
@ Sebelas Lu itu tergantung pada perangkat Anda. Misalnya pada yang lebih baru, seperti alokasi iPhone5 atau iPad4 70 Mb tidak masalah sama sekali.
Maks
1
ya tapi saya ingin tahu apakah saya bisa memastikan bahwa selama saya menjaga total penggunaan aplikasi saya di bawah anggaran memori khusus perangkat magis itu tidak akan dihentikan!
Steven Lu
1
tidak ada jaminan
Maks
421

Hasil pengujian dengan utilitas Split menulis (tautan ada dalam jawabannya):

perangkat: (jumlah kerusakan / jumlah total / persentase total)

  • iPad1: 127MB / 256MB / 49%
  • iPad2: 275MB / 512MB / 53%
  • iPad3: 645MB / 1024MB / 62%
  • iPad4: 585MB / 1024MB / 57% (iOS 8.1)
  • iPad Mini Generasi Pertama: 297MB / 512MB / 58%
  • iPad Mini retina: 696MB / 1024MB / 68% (iOS 7.1)
  • iPad Air: 697MB / 1024MB / 68%
  • iPad Air 2: 1383MB / 2048MB / 68% (iOS 10.2.1)
  • iPad Pro 9.7 ": 1395MB / 1971MB / 71% (iOS 10.0.2 (14A456))
  • iPad Pro 10.5 ": 3057/4000/76% (iOS 11 beta4)
  • iPad Pro 12.9 ”(2015): 3058/3999/76% (iOS 11.2.1)
  • iPad Pro 12.9 ”(2017): 3057/3974/77% (iOS 11 beta4)
  • iPad Pro 11.0 ”(2018): 2858/3769/76% (iOS 12.1)
  • iPad Pro 12.9 ”(2018, 1TB): 4598/5650/81% (iOS 12.1)
  • iPad 10.2: 1844/2998/62% (iOS 13.2.3)
  • iPod touch 4th gen: 130MB / 256MB / 51% (iOS 6.1.1)
  • iPod touch 5th gen: 286MB / 512MB / 56% (iOS 7.0)
  • iPhone4: 325MB / 512MB / 63%
  • iPhone4s: 286MB / 512MB / 56%
  • iPhone5: 645MB / 1024MB / 62%
  • iPhone5s: 646MB / 1024MB / 63%
  • iPhone6: 645MB / 1024MB / 62% (iOS 8.x)
  • iPhone6 ​​+: 645MB / 1024MB / 62% (iOS 8.x)
  • iPhone6s: 1396MB / 2048MB / 68% (iOS 9.2)
  • iPhone6s +: 1392MB / 2048MB / 68% (iOS 10.2.1)
  • iPhoneSE: 1395MB / 2048MB / 69% (iOS 9.3)
  • iPhone7: 1395 / 2048MB / 68% (iOS 10.2)
  • iPhone7 +: 2040MB / 3072MB / 66% (iOS 10.2.1)
  • iPhone8: 1364 / 1990MB / 70% (iOS 12.1)
  • iPhone X: 1392/2785/50% (iOS 11.2.1)
  • iPhone XS: 2040/3754/54% (iOS 12.1)
  • iPhone XS Max: 2039/3735/55% (iOS 12.1)
  • iPhone XR: 1792/2813/63% (iOS 12.1)
  • iPhone 11: 2068/3844/54% (iOS 13.1.3)
  • iPhone 11 Pro Max: 2067/3740/55% (iOS 13.2.3)
Jasper
sumber
2
iPhone4: nilai serupa dikonfirmasi, tampaknya sah: P
cprcrack
3
iPhone 5 macet pada ± 645 MB.
asp_net
4
@JasperPol Saya telah mengedit posting Anda untuk memasukkan berbagai perangkat yang saya miliki, saya harap tidak apa-apa. Saya telah menambahkan versi iOS yang saya uji seandainya ada masalah, tetapi jangan ragu untuk menghapusnya jika menurut Anda itu tidak penting.
JosephH
2
Luar biasa bahwa daftar ini telah dibuat dan dikelola. Dalam pengalaman saya, saya harus menyimpan memori jauh lebih rendah agar aman, mungkin 20% dari apa yang ditampilkan di sini. Perbedaan perangkat ke perangkat juga sangat bervariasi.
user1021430
1
Baru saja menjalankan ini pada iPad Pro 12,9. Peringatan memori pada 2451MB, crash pada 3064MB, total 3981MB.
kunci
134

Saya membuat utilitas kecil yang mencoba mengalokasikan memori sebanyak mungkin untuk crash dan merekam ketika peringatan dan crash memori terjadi. Ini membantu untuk mengetahui berapa anggaran memori untuk perangkat iOS apa pun.

https://github.com/Split82/iOSMemoryBudgetTest

Membagi
sumber
Saya membuat tes yang menarik: menjalankan aplikasi saya dengan penggunaan memori pemantauan xcode, memasukkan latar belakang, menjalankan BudgetTest. Tes ini terbunuh sementara aplikasi di latar belakang saya tidak. Saya tertarik mengetahui mengapa. Juga, ini bertentangan dengan apa yang dikatakan @cprcrack pada jawaban lainnya.
Roberto
19

Dalam aplikasi saya, pengalaman pengguna lebih baik jika lebih banyak memori digunakan, jadi saya harus memutuskan apakah saya benar-benar harus membebaskan semua memori yang saya bisa masuk didReceiveMemoryWarning. Berdasarkan jawaban Split dan Jasper Pol, menggunakan maksimum 45% dari total memori perangkat tampaknya merupakan ambang batas yang aman (terima kasih kawan).

Jika seseorang ingin melihat implementasi aktual saya:

#import "mach/mach.h"

- (void)didReceiveMemoryWarning
{
    // Remember to call super
    [super didReceiveMemoryWarning];

    // If we are using more than 45% of the memory, free even important resources,
    // because the app might be killed by the OS if we don't
    if ([self __getMemoryUsedPer1] > 0.45)
    {
        // Free important resources here
    }

    // Free regular unimportant resources always here
}

- (float)__getMemoryUsedPer1
{
    struct mach_task_basic_info info;
    mach_msg_type_number_t size = sizeof(info);
    kern_return_t kerr = task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &size);
    if (kerr == KERN_SUCCESS)
    {
        float used_bytes = info.resident_size;
        float total_bytes = [NSProcessInfo processInfo].physicalMemory;
        //NSLog(@"Used: %f MB out of %f MB (%f%%)", used_bytes / 1024.0f / 1024.0f, total_bytes / 1024.0f / 1024.0f, used_bytes * 100.0f / total_bytes);
        return used_bytes / total_bytes;
    }
    return 1;
}

Swift (berdasarkan jawaban ini ):

func __getMemoryUsedPer1() -> Float
{
    let MACH_TASK_BASIC_INFO_COUNT = (sizeof(mach_task_basic_info_data_t) / sizeof(natural_t))
    let name = mach_task_self_
    let flavor = task_flavor_t(MACH_TASK_BASIC_INFO)
    var size = mach_msg_type_number_t(MACH_TASK_BASIC_INFO_COUNT)
    var infoPointer = UnsafeMutablePointer<mach_task_basic_info>.alloc(1)
    let kerr = task_info(name, flavor, UnsafeMutablePointer(infoPointer), &size)
    let info = infoPointer.move()
    infoPointer.dealloc(1)
    if kerr == KERN_SUCCESS
    {
        var used_bytes: Float = Float(info.resident_size)
        var total_bytes: Float = Float(NSProcessInfo.processInfo().physicalMemory)
        println("Used: \(used_bytes / 1024.0 / 1024.0) MB out of \(total_bytes / 1024.0 / 1024.0) MB (\(used_bytes * 100.0 / total_bytes)%%)")
        return used_bytes / total_bytes
    }
    return 1
}
cprcrack
sumber
1
ukuran harus TASK_BASIC_INFO_COUNT bukan sizeof (info) - kesalahan ini disalin-tempel ke banyak tempat dengan kode yang sama
Maxim Kholyavkin
Terima kasih Speakus. Anda tampaknya benar berdasarkan tautan ini . Apakah Anda memiliki referensi lain di mana informasi ini dapat ditemukan?
cprcrack
apple menggunakan TASK_BASIC_INFO_COUNT terlalu
Maxim Kholyavkin
45% bukan batas aman lagi, terlalu dekat dengan nilai kerusakan 50% untuk iPhone X. Saya sarankan menggunakan 40%, atau nilai terpisah untuk setiap perangkat.
Slyv
8

Dengan memalsukan repo SPLITS, saya membuat satu untuk menguji memori iOS yang dapat dialokasikan ke Ekstensi Hari Ini

iOSMemoryBudgetTestForExtension

Berikut ini adalah hasil yang saya dapatkan di iPhone 5s

Peringatan Memori pada 10 MB

Aplikasi Hancur pada 12 MB

Dengan ini berarti Apple hanya mengizinkan ekstensi apa saja untuk bekerja dengan potensi penuh mereka .

Keras
sumber
7

Anda harus menonton sesi 147 dari video Sesi WWDC 2010 . Ini adalah "Advanced Performance Optimization pada iPhone OS, bagian 2".
Ada banyak saran bagus tentang optimasi memori.

Beberapa tipsnya adalah:

  • Gunakan bersarang NSAutoReleasePool untuk memastikan penggunaan memori Anda tidak lonjakan.
  • Gunakan CGImageSourcesaat membuat thumbnail dari gambar besar.
  • Tanggapi peringatan kehabisan memori.
Kobski
sumber
Pertanyaan saya bukan tentang bagaimana mengoptimalkan (terima kasih untuk tautannya), ini tentang seberapa banyak yang dapat kami izinkan untuk digunakan. Alasannya adalah bahwa misalnya, jika kami mengoptimalkan untuk mendapatkan 20mb, maka artis akan ingin menggunakan 20mb jika itu dalam "anggaran" yang masuk akal, alias yakin itu tidak akan menyebabkan masalah kinerja atau kerusakan memori.
frilla
BAIK. Kecelakaan akan terjadi karena OS menghentikan aplikasi karena keterbatasan memori. Anda bisa menambahkan bagian NSLogdalam didReceiveMemoryWarningdan kemudian melakukan beberapa pengujian di mana Anda mengalokasikan jumlah memori yang berbeda dan kemudian melihat kapan peringatan memori mulai muncul.
Kobski
4

Dimulai dengan iOS13, ada cara yang didukung Apple untuk menanyakan hal ini dengan menggunakan

#include <os/proc.h>

size_t os_proc_available_memory(void)

Diperkenalkan di sini: https://developer.apple.com/videos/play/wwdc2019/606/

Sekitar min 29-ish.

Sunting: Menambahkan tautan ke dokumentasi https://developer.apple.com/documentation/os/3191911-os_proc_available_memory?language=objc

Exaberri Tokugawa
sumber
Akhirnya! Saya menguji os_proc_available_memory () pada beberapa perangkat, dan hasilnya sangat mirip dengan nilai di tabel besar di atas!
Slyv
3
- (float)__getMemoryUsedPer1
{
    struct mach_task_basic_info info;
    mach_msg_type_number_t size = MACH_TASK_BASIC_INFO;
    kern_return_t kerr = task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &size);
    if (kerr == KERN_SUCCESS)
    {
        float used_bytes = info.resident_size;
        float total_bytes = [NSProcessInfo processInfo].physicalMemory;
        //NSLog(@"Used: %f MB out of %f MB (%f%%)", used_bytes / 1024.0f / 1024.0f, total_bytes / 1024.0f / 1024.0f, used_bytes * 100.0f / total_bytes);
        return used_bytes / total_bytes;
    }
    return 1;
}

Jika seseorang akan menggunakan TASK_BASIC_INFO_COUNT alih-alih MACH_TASK_BASIC_INFO, Anda akan mendapatkan

kerr == KERN_INVALID_ARGUMENT (4)

Dmitry Preobrazhenskiy
sumber
Anda setidaknya harus menyebutkan bahwa jawaban Anda hampir merupakan copy & paste tepat dari @ cprcrack di atas. Satu-satunya perbedaan adalah TASK_BASIC_INFO_COUNT.
mrvincenzo
2

Saya membuat satu daftar lagi dengan mengurutkan daftar Jaspers berdasarkan RAM perangkat (Saya membuat tes sendiri dengan alat Split dan memperbaiki beberapa hasil - periksa komentar saya di utas Jaspers).

RAM perangkat: rentang persen untuk crash

  • 256MB: 49% - 51%
  • 512MB: 53% - 63%
  • 1024MB: 57% - 68%
  • 2048MB: 68% - 69%
  • 3072MB: 63% - 66%
  • 4096MB: 77%
  • 6144MB: 81%

Kasus khusus:

  • iPhone X (3072MB): 50%
  • iPhone XS / XS Max (4096MB): 55%
  • iPhone XR (3072MB): 63%
  • iPhone 11/11 Pro Max (4096MB): 54% - 55%

Perangkat RAM dapat dibaca dengan mudah:

[NSProcessInfo processInfo].physicalMemory

Dari pengalaman saya, aman untuk menggunakan 45% untuk perangkat 1GB, 50% untuk perangkat 2 / 3GB dan 55% untuk perangkat 4GB. Persen untuk macOS bisa sedikit lebih besar.

Slyv
sumber
pembaruan: Tampaknya iPhone X merupakan pengecualian - crash ketika 50% RAM digunakan (diuji dengan aplikasi iOSMemoryBudgetTest). Saya memperbarui daftar.
Slyv
0

Bekerja dengan banyak jawaban di atas, saya telah menerapkan metode baru Apple os_proc_available_memory()untuk iOS 13+ ditambah dengan NSByteCountFormatteryang menawarkan sejumlah opsi format berguna untuk output memori yang lebih baik:

#include <os/proc.h>

....

- (NSString *)memoryStringForBytes:(unsigned long long)memoryBytes {
    NSByteCountFormatter *byteFormatter = [[NSByteCountFormatter alloc] init];
    byteFormatter.allowedUnits = NSByteCountFormatterUseGB;
    byteFormatter.countStyle = NSByteCountFormatterCountStyleMemory;
    NSString *memoryString = [byteFormatter stringFromByteCount:memoryBytes];
    return memoryString;
}

- (void)memoryLoggingOutput {
    if (@available(iOS 13.0, *)) {
        NSLog(@"Physical memory available: %@", [self memoryStringForBytes:[NSProcessInfo processInfo].physicalMemory]);
        NSLog(@"Memory A (brackets): %@", [self memoryStringForBytes:(long)os_proc_available_memory()]);
        NSLog(@"Memory B (no brackets): %@", [self memoryStringForBytes:(long)os_proc_available_memory]);
    }
}

Catatan penting: Jangan lupa ()pada bagian akhir. Saya telah memasukkan kedua NSLogopsi di dalammemoryLoggingOutput metode karena tidak memperingatkan Anda bahwa mereka hilang dan kegagalan untuk memasukkan tanda kurung mengembalikan hasil yang tak terduga namun konstan.

String yang dikembalikan dari metode memoryStringForBytesmenghasilkan nilai seperti:

NSLog(@"%@", [self memoryStringForBytes:(long)os_proc_available_memory()]); // 1.93 GB
// 2 seconds later
NSLog(@"%@", [self memoryStringForBytes:(long)os_proc_available_memory()]); // 1.84 GB
App Dev Guy
sumber