前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C# static

C# static

作者头像
JusterZhu
发布2023-10-25 10:52:58
1900
发布2023-10-25 10:52:58
举报
文章被收录于专栏:JusterZhuJusterZhu

在 C# 中,static 关键字被用来标识一个成员(变量、方法、属性等)属于类自身,而不是类的实例。这意味着,无论我们创建多少个类的实例,都只会有一个 static 成员的副本。static 成员保存在 CLR (Common Language Runtime) 的静态内存中,而非堆或栈。

关于 static 存储的一些主要特点:

  1. 生命周期: static 变量的生命周期与程序的生命周期相同。当程序开始时,它们被初始化,当程序终止时,它们被销毁。
  2. 存储位置: static 变量存储在托管堆(Managed Heap)上的高频段,而不是与对象实例一起存储。
  3. 共享性: 所有实例共享同一个 static 变量。
  4. 初始化: static 变量在 .NET CLR 加载包含该变量的类时被初始化。如果是值类型,将被初始化为其默认值;对于引用类型,如果没有明确赋值,将被初始化为 null
  5. 访问方式: static 变量可以直接通过类名进行访问,而不需要对类进行实例化。

static 在 C# 中充当了全局变量的角色,并且提供了一种控制变量生命周期和访问权限的方式。

什么是高频段(High Frequency Heap)

.NETCommon Language Runtime (CLR) 管理了一个叫做“高频段”(High Frequency Heap)的内存区域,它专门用于存储静态字段。换句话说,高频段是托管堆中的一块特殊区域,主要用于存储所有类型的静态字段。

以下是一些关于高频段的重要说明:

  1. 生命周期:由于静态字段共享在整个应用程序实例中,并且它们的生命周期与应用程序运行周期相同,因此这部分内存在应用程序启动时就被分配,并且在应用程序关闭时释放。
  2. 访问速度:通常来说,访问位于高频段的静态字段比访问常规托管堆的对象更快。这主要是因为这些字段在物理内存中的位置固定不变,所以可以直接访问。
  3. 引用类型的处理:对于引用类型的静态字段,其引用(即地址)保存在高频段,但其实际指向的对象数据仍然存储在托管堆的其他部分。

static修饰的含义

static 关键字可以用于修饰类的成员(变量、方法、属性)和类本身。每种情况下 static 的含义略有不同:

  1. 静态变量 (static variables): 当我们将变量声明为静态时,无论创建多少个类的实例,都只会有一个静态变量的副本。所有的实例都共享该静态变量。您可以直接通过类而不是类的实例来访问静态变量。
  2. 静态方法 (static methods): 静态方法也是与类相关联,而非类的实例。因此,无需创建类的实例即可调用静态方法。静态方法只能访问静态变量或其他静态方法,它们不能访问类的非静态成员。
  3. 静态属性 (static properties): 静态属性用于获取或设置静态数据成员的值。它们的工作方式类似于静态方法。
  4. 静态类 (static classes): 静态类是一种特殊类型的类,它不能被实例化。换句话说,如果你试图创建静态类的实例,编译器会报错。静态类只包含静态成员。这些类通常用于存储不会改变的数据或全局方法,例如 System.Math 类。

记住,static 成员是类级别的,不是实例级别的。静态成员属于整个类,而不是类的特定实例。

优点:

  1. 内存效率: 使用 static 可以提高内存的使用效率。由于 static 成员与类相关联,不论实例化多少个类,对于每个 static 成员都只会有一个副本。
  2. 全局访问: static 成员可以在没有创建对象的情况下被访问,因此它们可以被看作是全局变量。
  3. 生命周期: static 变量的生命周期为整个程序周期,因此可以用来存储在应用程序执行期间需要持久存在的信息。
  4. 控制实例数目: 通过将类的构造函数声明为 static,可以防止类被实例化,从而控制类的实例数量。

缺点:

  1. 内存占用: 尽管 static 变量在某些情况下可以提高内存效率,但由于它们在整个程序周期内都保持在内存中,因此可能导致过度的内存使用。
  2. 测试难度: static 成员可能使单元测试变得困难,因为它们在所有测试案例中都保持状态。这可能导致一些副作用,影响测试结果。
  3. 并发问题: 在多线程环境中,static 变量需要额外的同步措施以防止竞态条件。
  4. 面向对象设计: 过度使用 static 可能会破坏面向对象的设计原则,如封装、继承和多态,因为 static 成员不能通过类的实例进行访问或重写。

静态变量不再被使用时,如何回收内存空间?

都知道静态变量的生命周期持续整个应用程序的运行期,然而有些策略可以帮助我们有效管理静态变量:

  1. **设为 null**:如果你确定一个静态变量不再需要使用,可以把它设置为 null。虽然这种做法并不能立即释放内存,但会让 .NET 的垃圾收集器(GC)在下一次运行时回收该内存区域。
  2. 避免过度使用静态变量:如果你担心静态变量导致的内存问题,可能最好的解决方案就是尽量避免使用静态变量。如果一个变量可以不是静态的,最好使它成为实例变量。这样,每当相关对象实例不再被引用时,垃圾收集器就能释放与该实例关联的内存。
  3. 使用 WeakReference:对于大型对象或数据结构,可以考虑使用 WeakReferenceWeakReference 允许其引用的对象被垃圾收集器回收,在没有强引用存在的情况下。

静态变量的内存管理是由 .NET Common Language Runtime (CLR) 自动处理的,并且开发者不能直接控制。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-10-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JusterZhu 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • static修饰的含义
  • 静态变量不再被使用时,如何回收内存空间?
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档