5

デバイス (iPad) のメモリが不足しているように見えるため、アプリを投棄しています。Instruments が私が約 80Mb を使用していて、デバイス上で他のアプリが実行されていないことを示しているため、何が起こっているのかを理解しようとしています。

iOS の Mach システムにメモリ統計を要求する次のコード スニペットを見つけました。

#import <mach/mach.h>
#import <mach/mach_host.h>

static void print_free_memory () {
mach_port_t host_port;
mach_msg_type_number_t host_size;
vm_size_t pagesize;

host_port = mach_host_self();
host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
host_page_size(host_port, &pagesize);       

vm_statistics_data_t vm_stat;

if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS)
    NSLog(@"Failed to fetch vm statistics");

/* Stats in bytes */
natural_t mem_used = (vm_stat.active_count +
                      vm_stat.inactive_count +
                      vm_stat.wire_count) * pagesize;
natural_t mem_free = vm_stat.free_count * pagesize;
natural_t mem_total = mem_used + mem_free;
NSLog(@"used: %u free: %u total: %u", mem_used, mem_free, mem_total);
}

この関数を使用して 3 つのメモリ値を取得すると、mem_used の合計がそれほど変化していなくても、mem_total の値がかなり下がっていることがわかります。2 つの連続した出力行を次に示します。

<Warning>: used: 78585856 free: 157941760 total: 236527616

いくつかのコードが実行されます....

<Warning>: used 83976192 free: 10551296 total: 94527488

つまり、157MB の空きメモリから 10MB の空きメモリに一気に移動しましたが、使用量は 78MB から 84MB にしか増加しませんでした。合計メモリは 236MB から 94MB に減少しました。

これは誰にとっても意味がありますか?この期間中、デバイスで実行されている他のアプリケーションはありません。デバイスは基本的に完全に私のアプリケーション専用である必要があります。

2 つのメモリ チェックの間に実行されるコードはすべてネイティブ C++ コードであり、Apple フレームワークとはまったく対話しません。実際、C++ ヒープからオブジェクトを割り当ておよび割り当て解除するためのメモリ システムへの呼び出しは非常に多くありますが、見られるように、最終的に割り当てられるのは約 4MB の追加メモリのみであり、残りはすべて解放/削除されます。

不足しているメモリがヒープの断片化によって消費されている可能性がありますか? つまり、ヒープが単純に断片化されているため、ブロックのオーバーヘッドが追加の未確認のメモリをすべて消費しているのでしょうか?

他の誰かがこの動作を見たことがありますか?

ありがとう、

-エリック

4

1 に答える 1

10

アプリケーションのメモリ使用量を取得するtask_info代わりに使用する必要があります。host_statistics

# include <mach/mach.h>
# include <mach/mach_host.h>

void dump_memory_usage() {
  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 ) {
    NSLog( @"task_info: 0x%08lx 0x%08lx\n", info.virtual_size, info.resident_size );
  }
  else {
    NSLog( @"task_info failed with error %ld ( 0x%08lx ), '%s'\n", kerr, kerr, mach_error_string( kerr ) );
  }
}
于 2011-06-24T15:08:14.050 に答える