zoukankan      html  css  js  c++  java
  • C#托管堆和垃圾回收

    垃圾回收

    • 值类型
      • 每次使用都有对应新的线程栈 用完自动释放
    • 引用类型
      • 全局公用一个堆 因此需要垃圾回收
    • 操作系统
      • 内存是链式分配
    • CLR
      • 内存连续分配(数组) 要求所有对象从 托管堆分配
    • GC
      • 触发条件
        • New对象时 计算是否有足够的空间来分配该对象 若空间不足 则CLR就执行GC
        • 显示调用Collect 强制回收
        • Windows报告内存过低
        • CLR 卸载AppDomain时 CLR认为不存在根 开始对所有代进行GC
        • CLR正在关闭 进程要终止了
      • 垃圾回收算法-- 引用跟踪算法
        • 该算法只关心引用变量--因为引用变量才能引用堆上对象、值类型直接包含类型实例
        • 所有引用类型变量都称为--
      • GC过程
        • 暂停进程中所有线程
        • CLR进入GC标记阶段 遍历堆中所有对象 将同步块索引字段中的位设为0(表明所有对象都应删除)
        • 检查所有活动根 查看根所引用的对象 所有被引用对象的同步块索引字段中的位设为1 进行标记(对象被标记后 CLR会检查被标记对象中的根 并标记它们引用的对象 如果一个对象已被标记 则不重新检查该对象 避免死循环) 【已标记对象-- 可达对象 反之 不可达对象
        • GC开始压缩--删除不可达对象 并将可达对象 移动至一块连续的内存空间 【内存连续 实现了引用的 局部化 减少了程序的工作集 提高了访问性能】
      • GC常见BUG
        • OutOfMemoryException--若CLR在GC后没有回收到足够内存 无法对新对象进行分配 便会抛此异常(其中静态字段引用对象 会一直存在知道AppDomain卸载为止 所以让静态字段引用某个集合对象 然后不停的向集合添加数据 常常是内存泄漏的原因之一)
        • 引用对象 t=null 并不会实现对象的回收 因为JIT编译器是一个优化编译器 对于将局部变量或参数设为null时 JIT会将t=null 整行代码优化掉
      • 性能提升--基于代的垃圾回收器
        • 只支持3代 0代 1代 2代 经历一次GC 代会提升一次 0代总是最新的对象 2代是最老的对象 很少回收2代变量 CLR初始化时 会为每一代选择预算内存大小
        • 垃圾回收器每次会根据引用 构建 可达对象图 再根据可达对象图 进行回收 提高性能
        • CLR的垃圾回收器是自调节的 会自动根据程序需求调节代的内存分配
      • GC模式
        • 工作站模式--客户端应用程序优化
        • 服务器模式--主要优化吞吐量、资源利用
  • 相关阅读:
    神经网络加速与模型压缩
    字符串分割函数
    物体检测整理
    deeplab算法解析
    kmeans算法
    封装caffe版的deeplab为库供第三方使用
    进程 守护
    socketserver tcp黏包
    计算机
    网络 协议 2
  • 原文地址:https://www.cnblogs.com/Alicia-meng/p/13339990.html
Copyright © 2011-2022 走看看