堆和栈的功能简述

来源:互联网 发布:软件开发企业税率 编辑:程序博客网 时间:2024/06/05 19:29
我们在进行语言学习时,经常碰到内存的问题,这篇博文是简要的阐述内存中堆和栈的相关知识。

通过今天的学习,我们知道,运行时,内存一般分为若干部分,但是最重要的两部分是

首先说堆。在代码执行的过程中,堆中主要存放引用类型的对象。简单的来说,任何需要new出来的对象,都是存放在堆内存中。再次说栈。所有局部变量都存放在栈中。简单的来说,就是在任何一个方法中定义的变量,都存放在栈中。那么还剩下一个特殊类型的变量,就是值类型的变量的存放地址。因为值类型的变量在定义时我们是要分情况的。当值类型的变量在类中直接定义时,它是作为类的属性;而当它在类的某个方法中定义时,它是一个局部变量。在这两种情况下,值类型作为类的属性时,它保存在堆中;值类型作为局部变量时,它保存在栈中。我们举个例子来分析一下:
public class Custom{    int x;    public void SetX(int p_x){        x = p_x;    }}public class Main : MonoBehaviour{    void Awake(){        Custom cus = new Custom();      //---------1        int px = 5;                     //---------2        cus.SetX(px);                   //---------3    }}

我们这里主要分析,在程序默认执行Awake函数后,函数体内的各个语句的内存分布情况。
首先我们看第1行的代码“Custom cus = new Custom();” 因为执行的语句是在Awake方法中,此时=号左边是定义了一个Custom类型的局部变量cus,因此会在栈中分配一个内存给cus;然后我们再看=号右边是new 了一个Custom类的实例,因为它是new出来的,所以它表示在堆中分配了一块内存给这个Custom类作为一个实例。 而中间 = 号的作用即表示 栈中的内存 cus 指向 堆中的内存 Custom类的实例。

再看第2行代码。“int px = 5;” 很好理解,定义了一个值类型的局部变量px,也就是它的内存分配在栈中,且它的值为5.

最后看第3行代码。”cus.SetX(px);” 这行代码是对cus变量进行操作。我们知道,cus是保存在栈中的一个引用类型的变量,它指向堆中的一个Custom类的实例。而这个Custom类中定义了一个int类型变量,和一个方法。因为int类型的x是放在类的定义中的,它属于类的一个属性,因此它的内存会和Custom实例一样分配在堆中。而在执行SetX方法时,首先我们定义了一个局部变量p_x,它分配在栈中;其次我们改变了x的值,即改变了堆中x的值。

大致的堆与栈分配的原则如此。

最后顺便提一下,string类型不是基本类型,它是引用类型,看一下代码:

string str1 = "Hello";string str2 = "Hello";debug.log(str1 == str2);debug.log(str1.equals(str2));

上面的代码结果在计算中执行的记过是: false true。
原因是string 是 引用类型,当用== 进行比较的时候,其实是比较的str1 和str2 所指向的内存地址,而虽然str1 和str2 所指向的内存地址里的值是相同的,但是他们属于两个不同的地址,因此,str1 != str2.
当用equals方法进行比较的时候,它们就单纯的比较str1 与str2的值,因此返回true。

0 0
原创粉丝点击