【C#】内存的使用和释放

news2024/9/20 20:09:20

在 C# 中,内存管理主要是由 .NET 的垃圾回收器(Garbage Collector, GC)自动处理的。然而,了解如何正确地使用和释放内存对于编写高效且可靠的代码非常重要。以下是一些关键点和最佳实践:

1. 内存分配

  1. 托管资源

    • 托管资源是由 CLR 自动管理的,例如对象实例、字符串等。
    • 当创建一个对象时,CLR 会从托管堆中分配内存。
  2. 非托管资源

    • 非托管资源包括文件句柄、数据库连接、GDI+ 对象等。
    • 这些资源需要显式地释放,通常通过实现 IDisposable 接口来完成。

2. 内存释放

  1. 垃圾回收器

    • 垃圾回收器定期运行,查找不再被引用的对象,并回收它们占用的内存。
    • 垃圾回收器将内存分为三代(Gen 0, Gen 1, Gen 2),根据对象的生命周期进行不同的处理。
  2. 终结器(Finalizer)

    • 终结器是一个特殊的方法,用于在对象被垃圾回收之前执行清理工作。
    • 终结器通常用于释放非托管资源,但不推荐频繁使用,因为它们会增加垃圾回收的复杂性和开销。
  3. IDisposable 接口

    • 实现 IDisposable 接口可以显式地控制资源的释放。
    • 使用 using 语句可以确保资源在作用域结束时被正确释放。

3. 示例代码

3.1 托管资源的使用和释放

public class ManagedResource
{
    // 构造函数
    public ManagedResource()
    {
        Console.WriteLine("ManagedResource created.");
    }

    // 析构函数(可选)
    ~ManagedResource()
    {
        Console.WriteLine("ManagedResource finalized.");
    }
}

public class Program
{
    static void Main()
    {
        ManagedResource resource = new ManagedResource();
        // 使用资源...
        
        // 资源会在适当的时候被垃圾回收器自动回收
    }
}

3.2 非托管资源的使用和释放

using System;

public class UnmanagedResource : IDisposable
{
    private IntPtr _handle; // 模拟非托管资源
    private bool _disposed = false;

    public UnmanagedResource()
    {
        _handle = IntPtr.Zero; // 分配非托管资源
        Console.WriteLine("UnmanagedResource created.");
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                // 释放托管资源
            }

            // 释放非托管资源
            if (_handle != IntPtr.Zero)
            {
                // 释放非托管资源
                Console.WriteLine("UnmanagedResource released.");
                _handle = IntPtr.Zero;
            }

            _disposed = true;
        }
    }

    ~UnmanagedResource()
    {
        Dispose(false);
    }
}

public class Program
{
    static void Main()
    {
        using (var resource = new UnmanagedResource())
        {
            // 使用资源...
        }

        // 资源在 using 语句块结束时被自动释放
    }
}

4. 最佳实践

  1. 使用 using 语句

    • 对于实现了 IDisposable 接口的对象,使用 using 语句确保资源在作用域结束时被正确释放。
  2. 避免不必要的对象创建

    • 尽量减少临时对象的创建,特别是在循环中。
  3. 及时释放非托管资源

    • 如果类使用了非托管资源,确保实现 IDisposable 接口,并在 Dispose 方法中释放这些资源。
  4. 避免显式调用 GC.Collect()

    • 除非有明确的理由,否则不要显式调用 GC.Collect(),因为这会影响性能并干扰垃圾回收器的正常工作。
  5. 避免滥用终结器

    • 只有在确实需要释放非托管资源时才使用终结器。大多数情况下,应优先使用 IDisposable 接口。
  6. 使用弱引用

    • 对于那些可以被垃圾回收器回收的对象,可以考虑使用 WeakReference 类,以避免强引用导致对象无法被回收。

通过遵循这些最佳实践,可以更有效地管理和优化 C# 应用程序中的内存使用。

5. 解决内存已损坏

【C#】未处理System.AccessViolationExceptionHResult=-2147467261Message=尝试读取或写入受保护的内存。这通常指示其他内存已损坏。_system.accessviolationexception:“尝试读取或写入受保护的内存。这通常-CSDN博客文章浏览阅读1.3k次,点赞9次,收藏10次。【C#】未处理System.AccessViolationExceptionHResult=-2147467261Message=尝试读取或写入受保护的内存。这通常指示其他内存已损坏。_system.accessviolationexception:“尝试读取或写入受保护的内存。这通常指示其他https://blog.csdn.net/wangnaisheng/article/details/139679402

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2149945.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何查询论文的SCI检索号?

一、登录Web of Science 不要自己登录,需要选择机构为CHINA CERNET Federation,否则无法查询文章。 然后转到机构,选择对应的大学。 更具对应文章名查询文献。 二、查询文献名

python基础知识(六)--字典遍历、公共运算符、公共方法、函数、变量分类、参数分类、拆包、引用

字典遍历方法 函数名含义keys()以列表的形式,返回一个字典所有的键。values()以列表的形式,返回一个字典所有的值。items()返回由键值组成的序列,主要应用于遍历字典。 公共运算符 运算符描述支持的容器类型合并字符串、列表、元组*复制字符…

linux入门到实操-9 linux文件操作命令:创建文件、复制文件或文件夹、删除和移动文件、多种查看文件的方法

教程来源:B站视频BV1WY4y1H7d3 3天搞定Linux,1天搞定Shell,清华学神带你通关_哔哩哔哩_bilibili 整理汇总的课程内容笔记和课程资料(包含课程同版本linux系统文件等内容),供大家学习交流下载:…

PHP限定post提交数据的次数

PHP限定post提交数据的次数。 在PHP中&#xff0c;你可以通过记录IP地址的提交次数并在会话或数据库中存储这些信息来实现这个需求。以下是一个简单的PHP示例&#xff0c;它使用会话来跟踪IP地址的提交次数。 <?php session_start(); // 获取用户的IP地址 $ip_address $…

迁移学习+多模态融合,小白轻松发一区!创新性拉满!

多模态研究如今愈发火热&#xff0c;已成为各大顶级会议的投稿热门。今天&#xff0c;我为大家提供一个多模态的创新思路&#xff1a;迁移学习与多模态融合。 迁移学习多模态融合方向的优势 1.提升模型性能&#xff1a;综合更多维度优势&#xff0c;跨模态互补 2.快速适应新…

计算机网络 --- 初识协议

序言 上一篇文章中 &#xff08;&#x1f449;点击查看&#xff09;&#xff0c;我们简单的了解了怎么寻找目标计算机&#xff0c;需要通过交换机&#xff0c;路由器等设备跨越多个网络来不断的转发我们需要传输的数据&#xff0c;直至到达目标计算机。  那我们设备之间数据是…

挖矿病毒排查演示

1、上传病毒文件到/opt目录中 2、把压缩文件名修改成virus.zip 3、检查一下/etc/passwd ​ root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:…

GeoGebra 與數學探索 3 GeoGebra 在微積分的探索與動態演示

Goal: GeoGebra 除了可以輕鬆的讓我們以即時動態反饋圖形的方式模擬探索幾何的問題, 或是幫我們驗證答案, 也可以進行數論、微積分、矩陣等等各方面的探索, 在問題尺度不大又需要即時以圖像視覺呈現探索過程的情況下, GeoGebra 其實優於以寫程式的方式進行探索. “Talk is che…

unordered_map/set(底层实现)——C++

目录 前言&#xff1a; 1.开散列 1. 开散列概念 2. 开散列实现 2.1哈希链表结构体的定义 2.2哈希表类即私有成员变量 2.3哈希表的初始化 2.4迭代器的实现 1.迭代器的结构 2.构造 3.* 4.-> 5. 6.&#xff01; 2.5begin和end 2.6插入 2.7Find查找 2.8erase删除 3.unordered_ma…

mybatisplus中id生成策略

使用Tableld(value,type) 1.typeIdType.AUTO自增主键 2.typeIdType.ASSIGN,雪花算法生成 mybatisplus id生成策略全局配置 配置表前缀以及id生成策略 mybatis-plus:global-config:db-config:id-type: autotable-prefix: :t_

热点|创邻图查询范式引爆LDBC TUC2024

2024年8月30日至31日&#xff0c;创邻科技Galaxybase团队联合蚂蚁集团TuGraph团队、阿里巴巴GraphScope团队共同主办第18届LDBC TUC会议。在本次会议中&#xff0c;来自全球图数据库领域的学者和技术专家做了很多精彩的分享&#xff0c;共同探讨图技术的最新进展。创邻科技Gala…

EC Shop安装指南 [ Apache PHP Mysql ]

这个是软件测试课上老师布置的一个作业&#xff0c;期间老师也出现了不少错误&#xff0c;所以还是有必要记录一下吧&#xff0c;凑一篇文章 主要是老师的文档以及自己的一些尝试记录&#xff0c;试错记录&#xff0c;解决方案等 主要介绍了Apache的安装&#xff0c;MySQL的安…

weblogic CVE-2020-14882 靶场攻略

漏洞描述 32 CVE-2020-14882 允许远程⽤户绕过管理员控制台组件中的身份验证。 CVE-2020-14883 允许经过身份验证的⽤户在管理员控制台组件上执⾏任何命令。 使⽤这两个漏洞链&#xff0c;未经身份验证的远程攻击者可以通过 HTTP 在 Oracle WebLogic 服务器上执⾏任意命令并…

基于协同过滤算法+PHP的新闻推荐系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于协同过滤算法PHPMySQL的新…

基于Java的房地产在线营销管理系统研究与实现

目录 前言 功能设计 系统实现 获取源码 博主主页&#xff1a;百成Java 往期系列&#xff1a;Spring Boot、SSM、JavaWeb、python、小程序 前言 随着信息技术的迅猛发展&#xff0c;互联网已经渗透到我们生活的方方面面&#xff0c;为各行各业带来了前所未有的变革。房地产…

条件编译代码记录

#include <iostream>// 基类模板 template<typename T> class Base { public:void func() {std::cout << "Base function" << std::endl;} };// 特化的子类 template<typename T> class Derived : public Base<T> { public:void…

8585 栈的应用——进制转换

### 思路 1. **初始化栈**&#xff1a;创建一个空栈用于存储转换后的八进制数的每一位。 2. **十进制转八进制**&#xff1a;将十进制数不断除以8&#xff0c;并将余数依次入栈&#xff0c;直到商为0。 3. **输出八进制数**&#xff1a;将栈中的元素依次出栈并打印&#xff0c;…

navicate连接oracle数据库probable oracle net admin error

没用过oracle数据库 1、数据库版本19c&#xff1b; 使用dbeaver连接是没有问题的 使用navicate一直报错 解决方案&#xff1a; oracle官网下载win64的OCI环境 https://www.oracle.com/database/technologies/instant-client/winx64-64-downloads.html 下载好的压缩包直接解…

Git入门学习(1)

Git 00.准备工作-gitee注册 今天Git的设置中需要用到gitee的注册信息&#xff0c;先自行完成注册工作&#xff0c;可以 参考笔记 或第二天视频&#xff08;10.Git远程仓库-概念和gitee使用准备&#xff09; 传送门: gitee&#xff08;码云&#xff09;:https://gitee.com/ 注…

Hutool树结构工具-TreeUtil构建树形结构

1 pom.xml <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.26</version> </dependency> 2 核心代码 import cn.beijing.satoken.domain.ZhiweiCityArea; import cn.beijing.sa…