<commit_before>---
layout: post
title: OC中的内存管理其一
category: iOS开发
---

## 前言

> 本文的内容由我个人通过阅读《Objective-C高级编程》 总结而来，尽管第一章作者命名为自动引用计数，但经过我个人理解，第一章的内容已经显然超过单纯介绍自动引用计数，而是比较全面的介绍了OC中内存管理的前世今生，因此我认为“内存管理”更适合作为本章的标题，文中的内容并非完全来自书中，其中也加入了我通过查阅获取的知识，以及我个人的一些见解。

## C语言中的内存管理

在了解OC的内存管理之前，我们首先要知道OC这种语言是C语言的超集，因此了解C语言的内存管理是必不可少的前置基础。

操作系统在加载了C代码后会将内存分为四种区域（这四种区域并非完全是连续的，我注意到有些博客将内存模型以图示的方式将一个内存分为四块，但这容易使人们误以为它们是四块连续的区域。）接着我们来一一了解这四种区域，但由于深入理解可能会偏离主题，因此每种区域只做必要的介绍。

### 栈（stack）

+ 这是一块连续内存区域，它的大小在编译期就已经确定，我们常说它是由编译器决定的（当然最终还是人类决定的），空间也非常有限。
+ 这一块区域存放的是局部变量。
+ 内存空间的申请和释放也是由编译器自动完成，我们只需要声明和赋值，内存便会自动申请，当执行到局部变量作用域的末尾，内存也会自动释放。

### 堆 （heap）

+ 堆是内存中不连续的部分，它的空间很大，受限于系统和应用程序的寻址范围，以及计算机的虚拟内存大小，当然最终还是受限于编译器，理论上而言32位的应用程序中堆的空间最大为4G（但是不会达到这个数字，编译器会对它进行限制，因为其他的区域会占用一部分内存，操作系统也会占用一部分内存）。
+ 这一块区域存放的是我们在代码中动态申请（malloc、calloc、realloc）
的内容
+ 当申请的内容不再需要时，我们需要在代码中主动释放它们（free），如果不释放，那么这一块内存将会一直被占用直到程序结束。（内存泄漏）


> 关于后面两个区域的介绍在网络上非常至少，绝大多数地方都是一笔带过，希望大家能补充，当然这两个区域我们也不必过多讨论

### 全局/静态区 （static）

+ 这个区域空间很大（具体多大不清楚，如何划分不清楚，是否连续不清楚，是否与堆共享不清楚）
+ 这个区域存放的是全局变量和静态变量。
+ 程序结束时释放。

### 常量区

+ 同样的，这个区域的空间依旧很大，但是细节都不清楚。
+ 这个区域存放各种常量。
+ 程序结束时释放。

（说实话我个人对常量区是否存在心存怀疑。）

## OC中的内存管理

我们使用这样的方式在OC中初始化一个对象实例：

```
MyObject *m = [[MyObject alloc]init];
```<commit_msg>no message<commit_after>---
layout: post
title: OC中的内存管理其一
category: iOS开发
---

## 前言

> 本文的内容由我个人通过阅读《Objective-C高级编程》 总结而来，尽管第一章作者命名为自动引用计数，但经过我个人理解，第一章的内容已经显然超过单纯介绍自动引用计数，而是比较全面的介绍了OC中内存管理的前世今生，因此我认为“内存管理”更适合作为本章的标题，文中的内容并非完全来自书中，其中也加入了我通过查阅获取的知识，以及我个人的一些见解。

## C语言中的内存管理

在了解OC的内存管理之前，我们首先要知道OC这种语言是C语言的超集，因此了解C语言的内存管理是必不可少的前置基础。

操作系统在加载了C代码后会将内存分为四种区域（这四种区域并非完全是连续的，我注意到有些博客将内存模型以图示的方式将一个内存分为四块，但这容易使人们误以为它们是四块连续的区域。）接着我们来一一了解这四种区域，但由于深入理解可能会偏离主题，因此每种区域只做必要的介绍。

### 栈（stack）

+ 这是一块连续内存区域，它的大小在编译期就已经确定，我们常说它是由编译器决定的（当然最终还是人类决定的），空间也非常有限。
+ 这一块区域存放的是局部变量。
+ 内存空间的申请和释放也是由编译器自动完成，我们只需要声明和赋值，内存便会自动申请，当执行到局部变量作用域的末尾，内存也会自动释放。

### 堆 （heap）

+ 堆是内存中不连续的部分，它的空间很大，受限于系统和应用程序，以及计算机的虚拟内存大小，当然最终还是受限于编译器，理论上而言32位的应用程序中堆的空间最大为4G（但是不会达到这个数字，编译器会对它进行限制，因为其他的区域会占用一部分内存，操作系统也会占用一部分内存）。
+ 这一块区域存放的是我们在代码中动态申请（malloc、calloc、realloc）
的内容
+ 当申请的内容不再需要时，我们需要在代码中主动释放它们（free），如果不释放，那么这一块内存将会一直被占用直到程序结束。（内存泄漏）


> 关于后面两个区域的介绍在网络上非常至少，绝大多数地方都是一笔带过，希望大家能补充，当然这两个区域我们也不必过多讨论

### 全局/静态区 （static）

+ 这个区域空间很大（具体多大不清楚，如何划分不清楚，是否连续不清楚，是否与堆共享不清楚）
+ 这个区域存放的是全局变量和静态变量。
+ 程序结束时释放。

### 常量区

+ 同样的，这个区域的空间依旧很大，但是细节都不清楚。
+ 这个区域存放各种常量。
+ 程序结束时释放。

（说实话我个人对常量区是否存在心存怀疑。）

## OC中的内存管理

我们使用这样的方式在OC中初始化一个对象实例：

```
MyObject *m = [[MyObject alloc]init];
```
{'fraction_non_alphanumeric': 0.11560226354082458, 'fraction_numerical': 0.002425222312045271, 'mean_word_length': 12.451086956521738, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7538918', 'n_tokens_mistral': 2263, 'n_tokens_neox': 2609, 'n_words': 81}