在了解GC之前,我们应该先了解一下,线程栈和进程堆;
堆 Heap: 进程堆,一个程序在运行时,进程对方引用类型变量的一块内存,全局唯一;
栈 Stack: 线程栈,一个线程存放变量的一个内存,随着线程的生命周期存在而存在;
引用类型:类/接口/委托 ,存放在堆上;
值类型:结构/枚举 , 存放在栈;
经过上面了解,值类型是不会被GC回收,因为值类型存放在线程栈上,它会随着线程的结束而自动释放。
1.GC,只有引用类型才会被垃圾回收?
只有托管资源在才会被回收;(托管资源:托管在CLR上,如对象的创建,string等;非托管资源:如数据链接、文件流、句柄等;非托管资源需要手动释放)
2.哪些对象的内存,会被GC回收?
对象访问不到了,就可以被GC回收;(程序入口--找对象--建立一个标记--对象图---如果访问不到的就是垃圾)
3.对象是如何分配再堆上的呢?
因为引用类型是分配再堆上面,每次分配的时候会先检查一个空间是否足够;
4.什么时候需要执行GC ?
1.)创建对象的时候--会有一个临界点;
2.)可以手动触发 GC.Conllect 直接就去GC回收下;(但频繁GC会损耗性能)
3.)程序在退出的时候会执行GC;
5.GC 在回收的是的时候,是怎么样的呢?
多个对象--全部对象标记为垃圾--开始一个一个检查,如果可以访问到,就标记一下,会再次遍历去清除内存--产生不连续内存---地址移动--压缩--还需要修改变量指向;
6.垃圾回收的策略是什么样的?
首先,对象分代:共3代;(优先回收0代,提高效率,最容易也是多需要回收的,如果0代回收之后,内存仍然不够----就去找1代 -----2代)
0代: 第一次分配到堆 就是0代;
1代: 被回收一次之后就由0代变成1代,依然存在;
2代: 被回收两次之后就由1代变成2代,依然存在;

网友评论