序文
iOS メモリ管理の最初の章では、iOS メモリの 5 つの主要なパーティションについて学びます。
概要
iOSでは、メモリは主にスタック領域、ヒープ領域、グローバル領域/静的領域、定数領域、コード領域の5つの主要な領域に分かれています。概要図は以下の通りです。
上図に示すように、コード領域は下位アドレスのセグメントに格納され、スタック領域は上位アドレスのセグメントに格納されており、パーティションは連続していません。
1.スタック
1.1 はじめに
- スタックとは、上位アドレスから下位アドレスまで格納される連続したメモリ領域であり、次のような特徴があります。
先进后出(FILO)
- iOSのスタックのアドレス空間が
0X7/ 0X16
始まり - 通常、スタック領域はそこにあります
运行时分配内存,内存空间由系统管理
。つまり、変数は独自のスコープを超えた後に解放されます。 - インクルード
函数内部定义的局部变量以及方法参数(方法的默认参数 self,cmd)
などもスタック領域に格納されます。
1.2 メリットとデメリット
- スタック領域のメモリはシステムによって割り当ておよび管理されるため、メモリの断片化を引き起こすことなくシステム自体によって割り当ておよび解放されるため、高速かつ効率的になります。
- ただし、スタックのメモリ サイズはシステムによって制限されているため、柔軟性があまり高くなく、iOS のメインスレッド スタックのサイズは 1MB、その他のスレッドは 512KB、Mac は 8M です。
- (void)testStack {
int a = 10;
NSLog(@"a == %p size == %lu",&a,sizeof(a));
NSLog(@"方法参数 self:%p",&self);
NSLog(@"方法参数 cmd:%p",&_cmd);
}
2. ヒープ領域
- ヒープは、下位アドレスから上位アドレスまでの不連続なメモリ領域であり、リンク リストの構造によく似ています (追加と削除は簡単ですが、クエリは簡単ではありません) 先入れ先出し FIFO が特徴です。
- ヒープ アドレスは 0X6 で始まり、スペースを動的に割り当てます。
- ヒープに格納されたものは手動で管理、解放する必要があり、解放が間に合わないとメモリリークが発生します。
- OC では、alloc と new はヒープ上にオブジェクト用のスペースを開きます。
- (void)testHeap {
NSObject *object1 = [NSObject new];
NSObject *object2 = [NSObject new];
NSLog(@"object1 = %@",object1);
NSLog(@"object2 = %@",object2);
}
スタックとヒープの違い
1. それぞれの長所と短所は何ですか?
- スタック:コンパイラによって自動的に割り当ておよび解放されるため、高速でメモリの断片化が発生しません。利点は高速で効率的であることですが、欠点は、場合によっては制限があり、データが柔軟性に欠けることです。
- ヒープ: プログラマによって割り当ておよび解放され、速度が遅くメモリの断片化が起こりやすいですが、使用するのが最も便利です。柔軟性と利便性、幅広いデータ適応性が利点ですが、効率は若干低下します。
2. 申請後のシステムの反応はどうなりますか?
- スタック:ストレージ: 各関数は、実行時にオペレーティング システムにリソースを要求します。スタック領域は、関数の実行時のメモリです。スタック領域内の変数は、コンパイラによって割り当ておよび解放されます。メモリは、機能が実行され、リリースはシステムによって自動的に完了します。スタックの残りのスペースが要求されたスペースよりも大きい限り、システムはプログラムにメモリを提供します。そうでない場合は、スタック オーバーフローを促す例外が報告されます。
- ヒープ:オペレーティング システムには、空きメモリ アドレスを記録するリンク リストがあります。システムはプログラムからアプリケーションを受け取ると、リンク リストを走査し、要求されたスペースより大きいスペースを持つ最初のヒープ ノードを探し、空きノードのリンク リストからそのノードを削除し、そのノードのスペースを割り当てます。プログラムすること。見つかったヒープ ノードのサイズは要求されたサイズと正確に一致しない可能性があるため、システムは自動的に余分な部分を空きリンク リストに戻します。
3. アプリケーションのサイズに制限はありますか?
- スタック: スタックは、下位アドレスまで拡張されるデータ構造であり、メモリの連続領域です。スタックの先頭アドレスとスタックの最大容量はシステムによってあらかじめ決められており、スタックのサイズは2M(1Mという説もありますが、要するにコンパイル時に決まる定数です)です。スタックの残りのスペースはオーバーフローを引き起こします。したがって、スタックから利用できるスペースは小さくなります。
- ヒープ: ヒープは、上位アドレスまで拡張されるデータ構造であり、不連続なメモリ領域です。これは、システムがリンク リストを使用して空きメモリ アドレスを格納するためであり、これらのアドレスは当然不連続であり、リンク リストのトラバース方向は下位アドレスから上位アドレスに向かうためです。ヒープのサイズは、コンピュータ システムで利用可能な仮想メモリによって制限されます。ヒープによって得られるスペースは、より柔軟でより大きいことがわかります。
3. グローバル/スタティックエリア
- この領域はコンパイル時に確保されるメモリ空間で、iOSでは通常、
0x1
プログラム実行中はこのメモリ内のデータが常に存在し、プログラム終了後にシステムによって解放されます。 - 初期化されていないグローバル変数と静的変数、
即BSS区(.bss)。
- 初期化されたグローバル変数と静的変数、
即数据区(.data)。
このうち、グローバル変数は実行時に動的に変更できる変数値を指しますが、静的変数は静的ローカル変数と静的グローバル変数を含む、静的に変更される変数です。 Static キーワードについての深い理解。
int clB;
static int bssB;
int initClB = 10;
static int initBssB = 11;
- (void)testStatic {
NSLog(@"clA = %p", &clB);
NSLog(@"bssB = %p", &bssB);
NSLog(@"initClB = %p", &initClB);
NSLog(@"initBssB = %p", &initBssB);
}
clB と bssB はどちらも初期化されておらず、メモリ内に連続したアドレスがあり、その差は 4 です。
initClB、initBssBともに初期化されたデータであり、メモリアドレスも連続しています。
4. 一定面積
- この領域はコンパイル時に確保されるメモリ空間で、プログラム実行中は常にこのメモリ上のデータが存在し、プログラム終了後にシステムにより解放されます。
- 定数を保存します。
整型、字符型、浮点、字符串等。
- 定数領域は、コンパイル中に割り当てられるメモリ領域です。プログラム終了後にシステムによって解放されます。主に次のものが格納されます。 ■ 使用されているがポイントしていない
文字列定数
■ プログラム内で複数回使用される文字列定数。したがって、メモリはプログラムの実行前に事前に割り当てられます。
5. コードエリア
- この領域はコンパイル時に確保されるメモリ空間で、プログラム実行中は常にこのメモリ上のデータが存在し、プログラム終了後にシステムにより解放されます。
- プログラム実行時のコードはバイナリにコンパイルされ、メモリのコード領域に格納されます。
要約する
iOS のメモリ領域について、主に明確に理解する必要があるスタックとヒープの違いと接続について予備的に理解しました。