GC回收之大对象和fixed

垃圾回收触发条件

  • CLR在检测到第0代超出预算时触发一次;
  • 显式调用 System.GC.Collect 方法;
  • Windows 通过Win32函数检测到内存低时触发;
  • CLR 正在卸载 AppDomain 时(一个AppDomain卸载时,CLR认为其中一切都不是根,执行一次涵盖所有代的GC);
  • CLR 正在关闭。CLR在进程正常终止时,CLR认为进程中的一切都不是根。但此时CLR不会视图压缩或释放内存,由Windows回收进程的全部内存。

大对象

大对象对于性能提升有很大影响。CLR将对象分为大对象和小对象,且以不同的方式对待他们。
CLR认为超过8500字节(约0.08M)或更大的对象是大对象。

  • 大对象不是在小对象的地址空间分配,而是在进程地址空间的其它地方分配;
  • 目前版本的GC不压缩大对象,移动他们代价较高,但可能造成地址空间碎片化,导致抛出 OutOfMemoryException;
  • 大对象总是在第2代,绝不可能在第0代或第1代。分配短时间存活的大对象会导致第2代频繁回收,损害性能;

大对象一般是大字符串(XML 或 JSON)或用于IO操作的字节数组;

fixed

1、fixed 语句禁止垃圾回收器重定位可移动的变量。fixed 语句只能出现在不安全的上下文中。Fixed 还可用于创建固定大小的缓冲区。
2、fixed 语句设置指向托管变量的指针并在 statement 执行期间“钉住”该变量。如果没有 fixed 语句,则指向可移动托管变量的指针的作用很小,因为垃圾回收可能不可预知地重定位变量。C# 编译器只允许在 fixed 语句中分配指向托管变量的指针。
3、执行完语句中的代码后,任何固定变量都被解除固定并受垃圾回收的制约。因此,不要指向 fixed 语句之外的那些变量。

posted @ 2022-02-22 11:15  江境纣州  阅读(238)  评论(0编辑  收藏  举报