"对象"这个词,在面对对象编程中,它指的是"具有属性和行为的事物",
而在GC的世界中,对象表示的是:"通过应用程序利用的数据的集合"
对象配置在内存空间里,GC根据情况将配置好的对象进行移动或者销毁,因此,对象是GC的基本单位.
一般来说,对象由 头(header) 和域(field)构成
保存对象本身信息的部位称为 "头",头主要含有以下信息:
1:对象的大小
2:对象的种类
此外,头还包含了运行GC所需要的信息,例如 标记-清除 算法,将会在头部设置一个flag 来记录对象是否已经标记
对象使用者在对象中可访问的部分称为 "域",类似于c语言中结构体的成员.
对象使用者会 引用/替换 对象的域值,但是对象使用者基本上无法直接更改头的信息
域中的数据类型大致分为以下2种:
1:指针类型
2:非指针类型
在对象域中,可以包含一个或多个新的对象,这就代表了子对象都处于该对象的域中,当该对象需要回收时,意味着域中的所有对象都可以回收(大多数情况下是的,但是可能出现内存逃逸,或者其他对象也引用了子对象的情况)
这个是Edsger Dijkstra 想出来的词,意思是改变某物的意思
在gc中,它的实体是应用程序,gc在mutator中运行,
操作应用程序中的对象
更新程序内的指针
堆在前文其实讲到过,就是动态存放对象的内存空间,
在mutator申请存放对象时,会从堆中分配给mutator
gc管理 堆中已经分配的对象,当堆占用到一定大小后,将启动gc清理垃圾对象
在程序运行之后, mutator会不停的更新创建对象,更新对象指针,例如:
#include<stdio.h>
#include<stdlib.h>
int inc();
int main() {
int a = 1;
int c = inc(a, 1);
printf("%d", c);
return 0;
}
int inc(int a, int b) {
return a + b;
}
当运行到int a = 1时,a对象将创建
运行到 inc函数时, inc 函数的a,b,将引用main中的a,1,意味着inc函数的 a,b引用了int a,
而再继续运行c时,其实 inc 函数里面的 a和b已经没有被mutator使用了
我们把能被mutator引用的对象称为:"活动对象"
不能被mutator 引用的称为:"非活动对象".也就是垃圾对象
分配(allocation)指的是在内存空间分配对象
当mutator需要新对象时,就会向分配器(allocator)申请一个大小合适的空间,分配器则在堆的可用空间内寻找满足要求的空间,返回给mutator
像java,go,这些配备了自动GC的编程语言中,会在内部进行自动分配,
而c语言则需要手动 使用malloc 进行分配
初始状态下,堆被一个大的分块所占据,然后程序会根据mutator的要求把分块分隔成合适的大小,给对象使用,对象转为非活动对象时将回收.
根指的是对象的指针的起点部分
在程序运行中,可以被mutator直接引用的对象 例如全局变量,调用栈,寄存器 都属于根的部分