当前位置:首页 > 数码 > C#开发三个关键的内存区域-非托管堆内存和栈内存-托管堆内存 (c#开发实战)

C#开发三个关键的内存区域-非托管堆内存和栈内存-托管堆内存 (c#开发实战)

admin4个月前 (05-01)数码45
对内存的治理和操作大部分都是由运转时处置的。开发者无需过多关注内存治理的细节,由于托管堆内存的渣滓回收机制可以智能处置对象的调配和监禁。但是,在特定状况下,如与非托管代码交互、启动性能优化或处置少量数据等,了解这些内存区域的概念和用法可以协助编写更高效和牢靠的代码。

简明说明

在C#中,存在三个关键的内存区域:托管堆内存、非托管堆内存和栈内存。上方关于这些内存区域的简明说明:

1、托管堆内存(ManagedHeapMemory):

C#

托管堆内存是由.NET运转时(CLR)智能治理的内存区域。

用于存储对象实例和数组等援用类型数据。

在堆上调配的内存会经过渣滓回收器(GarbageCollector)启动智能回收。

对象的创立和销毁都是由渣滓回收器担任治理。

usingSystem;classProgram{staticvoidMn(){//创立一个蕴含10个整数的数组int[]numbers=newint[10];//调配托管堆内存并存储数据for(inti=0;i<numbers.Length;i++){numbers[i]=i+1;}//计算数组中一切元素的总和intsum=0;for(inti=0;i<numbers.Length;i++){sum+=numbers[i];}Console.WriteLine($"数组中一切元素的总和为:{sum}");}}

在这个示例中,咱们创立了一个蕴含10个整数的数组numbers。经过经常使用new关键字,系统会在托管堆内存上灵活为数组调配空间。而后,咱们经常使用一个循环将数据存储到数组中。接上去,咱们计算数组中一切元素的总和。经过对数组启动循环访问,咱们可以一一访问数组元素并将它们累加到变量sum中。须要留意的是,托管堆内存的调配和监禁是由运转时环境智能处置的,咱们无需手动监禁内存。在程序口头终了后,运转时环境会智能回收托管堆内存。

2、非托管堆内存(UnmanagedHeapMemory):

非托管堆内存是由本机代码或外部资源调配的内存区域。

通罕用于与非托管代码启动交互、启动底层的系统编程或经常使用特定的外部库。

须要手动调配和监禁内存,没有智能渣滓回收的机制。

可以经常使用`Marshal`类或`unsafe`高低文来启动非托管内存的操作。

usingSystem;usingSystem.Runtime.InteropServices;classProgram{//导入非托管库[DllImport("unmanaged.dll")]privatestaticexternIntPtrAllocateMemory(intsize);[DllImport("unmanaged.dll")]privatestaticexternvoidFreeMemory(IntPtrpointer);staticvoidMain(){//调配非托管堆内存并存储数据intsize=10*sizeof(int);IntPtrpointer=AllocateMemory(size);unsafe{int*numbers=(int*)pointer;for(inti=0;i<10;i++){numbers[i]=i+1;}}//计算数组中一切元素的总和intsum=0;unsafe{int*numbers=(int*)pointer;for(inti=0;i<10;i++){sum+=numbers[i];}}Console.WriteLine($"数组中一切元素的总和为:{sum}");//监禁非托管堆内存FreeMemory(pointer);}}

在这个示例中,咱们经过申明DllImport个性来导入名为"unmanaged.dll"的非托管库。该库蕴含两个函数:AllocateMemory和FreeMemory,用于调配和监禁非托管堆内存。在Main方法中,咱们经常使用AllocateMemory函数调配一块大小为10个整数的非托管堆内存,并将其前往的指针存储在IntPtr类型的变量pointer中。接上去,咱们经常使用unsafe高低文将指针转换为int*类型的变量,并经过循环将数据存储到非托管堆内存中。而后,咱们经常使用另一个循环计算非托管堆内存中一切元素的总和。最后,咱们经常使用FreeMemory函数监禁非托管堆内存,确保将内存前往给操作系统。须要留意的是,经过平台调用或与非托管库交互时,须要分外小心和审慎,确保正确治理内存并防止内存走漏或其余不安保的操作。

3、栈内存(StackMemory):

栈内存用于存储部分变量、方法调用和口头高低文等信息。

存储的是值类型数据和援用类型数据的援用。

栈内存的调配和监禁是由编译器智能成功的,具备较高的效率。

栈内存的作用域仅限于所属的代码块或方法。

usingSystem;classProgram{staticvoidMain(){//申明和初始化变量inta=5;intb=10;//口头计算intsum=CalculateSum(a,b);//输入结果Console.WriteLine($"两数之和为:{sum}");}staticintCalculateSum(intx,inty){//在栈上调配内存,并启动计算intresult=x+y;//前往计算结果returnresult;}}

在这个示例中,咱们在Main方法中申明并初始化了两个整数变量a和b,它们被调配在栈上。而后,咱们调用CalculateSum方法,并将a和b的值作为参数传递给该方法。在CalculateSum方法中,参数x和y也是调配在栈上的部分变量。在方法体内,咱们将x和y相加,并将结果保留在名为result的部分变量中。最后,咱们经过return语句前往计算结果。须要留意的是,栈内存的生命周期与其所在的方法相关联。当方法调用完结时,栈上调配的部分变量将被智能监禁,不须要开发人员手动治理内存。经常使用栈内存可以提供极速的内存调配和监禁,由于它仅触及便捷的指针移动。但是,栈的大小是有限的,通常较小,因此栈内存关键用于存储暂时数据和部分变量。

优化技巧

了解和运行以下内存优化技巧可以协助提高性能并缩小内存消耗:

托管堆内存优化:

非托管堆内存优化:

栈内存优化:

其余优化技巧:

须要留意的是,对内存的治理和操作大部分都是由.NET运转时处置的。开发者无需过多关注内存治理的细节,由于托管堆内存的渣滓回收机制可以智能处置对象的调配和监禁。但是,在特定状况下,如与非托管代码交互、启动性能优化或处置少量数据等,了解这些内存区域的概念和用法可以协助编写更高效和牢靠的代码。


什么是C?

C是组合,与次序无关,A是排列,与次序有关;C的意思就是没有排列,组合到一起就行,与他们的次序没有关系;A的排列,就是有排列顺序。

C是组合,就是给你N个选择,你从中选择出不重复的K个,这就组合,比如说有一周有七天,让你选两天放假,这里有多少种可能的选择就有多少种组合。就以上面这个为例,怎么计算七天选两天,也就是C(7,2)。

扩展资料:

组合就到这里,接下来是排列组合,排列组合是在组合的基础上多了一个变化,它是有顺序的,比如刚才所说的,一周有七天,让你选两天放假,那么星期六、星期天和星期天、星期六实质上是同一种选择,因为它们没有顺序。

7*6是从7开始乘也就是C7的7,从7往下一共是2项,也就是C7取2的2,比如说如果改成C8取3,那么分子就是3*2*1=6,2这里的分母是2,实际上要分解为2*1,实质上分母就是2的阶乘,CN取K就是K的阶乘,比如说这里是C8取3那么分子就是3*2*1=6。

c是什么?

c是字母符号。

C(大写) 、c(小写)是英文字母顺数第三个,俄语字母顺数第19个。例如:英语单词cloud和“苏联”的俄语缩写СССР的第一个字母就是c。

起源:

(1)字母C的产生可能是由于一个投掷棒的符号,像在古埃及的象形文字里,并很早出现在闪族的书面当中-大约在公元前1500年的西奈半岛。

(2)大约在公元前1000年,在比布鲁斯(古地中海港市,位于现黎巴嫩贝鲁特以北的朱拜勒,公元前第二个千年成为繁华的腓尼基城)和腓尼基的其他一些地方以及迦南的中心,这个符号是特定的线性形式。

(3)对于全部的线性形式来说。在闪族的语言中这个符号叫做gimel或是gaml,意思是throwing stick(投掷棒)。

免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。

标签: C#

“C#开发三个关键的内存区域-非托管堆内存和栈内存-托管堆内存 (c#开发实战)” 的相关文章

与-终极指南-文件压缩-SharpZipLib-精通-พร้อม实用代码范例-DotNetZip-C (终极指南针官方网站)

与-终极指南-文件压缩-SharpZipLib-精通-พร้อม实用代码范例-DotNetZip-C (终极指南针官方网站)

目录压缩是一种将一系列文件或目录打包成单个存档文件的过程。此过程可用于备份、传输或节省磁盘空间。目录解压缩是将存档文件还原到其原始状态的过程。 有许多不同的目录压缩和解压缩工具可用。最流行的...

15-C-个顶级开源项目-中值得收藏的

15-C-个顶级开源项目-中值得收藏的

简介 MediatR 是 .NET 平台上一个轻量级库,它简化了命令查询责任分离 (CQRS) 模式的实现。CQRS 是一个设计模式,它将应用程序中的命令和查询分离成不同的组件。这可以提高应...

及其初级控件摸索之旅-深化了解跨平台开发畛域的弱小工具-C (及其初级控件有哪些)

及其初级控件摸索之旅-深化了解跨平台开发畛域的弱小工具-C (及其初级控件有哪些)

前几天一个学员在学习C#与初级控件交互时,也不知道初级控件可以用来做什么。 上方咱们就具体讲讲C#和初级控件交互的关系常识。 C#是一种配置丰盛的面向对象编程言语,它蕴含了许多初级控件...

C-线程本地存储-深化了解线程间值差别 (c++线程 window)

C-线程本地存储-深化了解线程间值差别 (c++线程 window)

为什么用ThreadStatic标志的字段,只要第一个线程拿到了初始值,其余线程都是自动值,让我能不能帮他解答一下,尼玛,我也不是神仙什么都懂,既然问了,那我试着帮他解答一下,也给前面相似不懂的好友解...

算法到-Python-客户端程序的综合指南-C-无缝集成 (算法到底应该怎么学?)

算法到-Python-客户端程序的综合指南-C-无缝集成 (算法到底应该怎么学?)

This example shows how to embed and execute an IronPython script in a C application. using IronP...

深入探索C中的LINQ魔法-功能概述和源代码剖析-b-b (进行深入探索)

深入探索C中的LINQ魔法-功能概述和源代码剖析-b-b (进行深入探索)

简介 LINQ(语言集成查询)是一种用于 C 中的数据查询和操作的强大工具。它允许开发人员使用类 C 语法而不是 SQL 语句来查询和操作各种数据源,例如集合、数组和 XML 文档。 20...

C-值传递与引用传递详解-中的参数传递 (c 值传递)

C-值传递与引用传递详解-中的参数传递 (c 值传递)

简介 C 是一种面向对象的编程语言,支持多种参数传递方式,包括传值和传引用两种方式。在本文中,我们将讨论 C 中的参数传递方式以及如何使用它们来实现不同的交互模式。 参数传递方式...