首页 > 系统相关 >.NET(C#) 内存堆和栈

.NET(C#) 内存堆和栈

时间:2024-01-20 22:13:04浏览次数:26  
标签:存储 C# Person int 对象 内存 NET

 

 参考文档:.Net(C#)内存堆和栈-CJavaPy

1、栈(Stack)

栈是一种线性数据结构,它以先进先出(LIFO)的方式管理数据。栈主要用于存储方法调用的信息,包括局部变量、方法参数和返回地址等。每个线程都有自己的栈。栈上的数据存储空间由编译器自动管理,因此它具有高速读写的特点。栈上的数据生命周期短暂,当一个方法结束时,它的栈中的数据就会被销毁。栈的操作通常更快,因为数据始终在栈顶进行增加或删除。存储基本数据类型(如 int, char, double)的值类型变量。存储引用类型的引用(即对象的地址)。方法的参数和局部变量通常存储在栈上。

2、堆(Heap)

堆是一种非线性数据结构,它用于存储动态分配的对象。堆上的数据由开发人员手动分配和释放,通常使用 new 操作符来创建对象。堆上的数据生命周期可以很长,直到没有引用指向这些对象时,它们才会被垃圾回收器回收。堆上的数据可以跨多个方法和线程访问,因此它们通常用于存储全局数据、对象和大型数据结构。存储引用类型的对象(如类实例、数组)。当使用 new 关键字创建对象时,对象被存储在堆上。

3、堆和栈的区别

在C#中,值类型(如整数、字符、布尔等)通常存储在栈上,而引用类型(如类、数组、接口等)的对象通常存储在堆上,但引用类型的引用本身可以存储在栈上。这是因为栈上的引用指向堆上的对象。

3)示例代码

using System;

class Person
{
    public string Name { get; set; }
    
    public Person(string name)
    {
        Name = name;
    }
}

class Program
{
    static void Main()
    {
        int x = 5; // 值类型,存储在栈上
        int y = 10; // 值类型,存储在栈上

        int sum = Add(x, y); // 方法调用,局部变量 sum 存储在栈上
        Console.WriteLine("Sum: " + sum); // 输出 Sum: 15

        Person person1 = new Person("C#"); // 创建 Person 对象,存储在堆上
        Person person2 = new Person("Java"); // 创建另一个 Person 对象,存储在堆上

        Console.WriteLine("Person 1: " + person1.Name); // 输出 Person 1: C#
        Console.WriteLine("Person 2: " + person2.Name); // 输出 Person 2: Java
    }

    static int Add(int a, int b)
    {
        return a + b;
    }
}

注意:了解内存中的堆和栈的区别对于编写高效的C#代码以及避免内存泄漏等问题非常重要。同时,C#的垃圾回收器会负责管理堆上的对象,使得开发人员不需要手动释放内存,但要注意及时清除不再使用的引用以便垃圾回收能够正常工作。

参考文档:.Net(C#)内存堆和栈-CJavaPy

标签:存储,C#,Person,int,对象,内存,NET
From: https://www.cnblogs.com/tinyblog/p/17977203

相关文章

  • AtCoder Beginner Contest 337
    A-Scoreboard思路&&Code/*高桥和青木N场比赛xy得分情况分别为x1y1.....xnyn计算高桥的总得分与青木的总得分进行比较高桥得分>青木得分输出Takahashi==输出Draw<输出Aoki*......
  • Luogu P4924 [1007] 魔法少女小Scarlet
    [1007]魔法少女小Scarlet\(\color{cyan}link\)题目描述Scarlet最近学会了一个数组魔法,她会在\(n\timesn\)二维数组上将一个奇数阶方阵按照顺时针或者逆时针旋转\(90^\circ\)。首先,Scarlet会把\(1\)到\(n^2\)的正整数按照从左往右,从上至下的顺序填入初始的二维数组......
  • 利用aop、拦截器HandlerInterceptor来实现接口限流,日志收集
    前言:aop是面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。拦截器是web请求中一个请求周期中的一环就实现接口限流这个需求来说,用aop和HandlerInterceptor都可以来实现,就是在调用接口之前做一些约束而已。aop+自定义注解+Semaphore实现接口限流自......
  • compareTo、Comparator、TreeSet排序那些事
    前言:对于后端开发而言,学会对数据的自定义排序还是十分有必要的。需要用到排序的场景也是很多的,什么排行版展示、利用时间+别的条件排序、还有预接单的数据就是要展示在已接单的数据前面这种需求、等等。总之很重要的!一:对集合排序对以下的数据做展示顺序排序:未接单>预接单>已接单。(......
  • HarmonyOS4.0系列——05、状态管理之@Prop、@Link、@Provide、@Consume,以及@Watch装饰
    状态管理看下面这张图Components部分的装饰器为组件级别的状态管理,Application部分为应用的状态管理。开发者可以通过@StorageLink/@LocalStorageLink实现应用和组件状态的双向同步,通过@StorageProp/@LocalStorageProp实现应用和组件状态的单向同步。@PropstaticProp(propName:......
  • 数据前置参数类型转换@InitBinder、Formatter<?>、Converter<?>的使用
    前言:在很多时候我们在进行调用接口的时候,传入的参数类型不是指定的特别明确(或者是不能进行自动类型转换),会导致调用接口失败的情况出现,如果我们在调用接口之前进行数据格式化,手动进行数据类型转换,那么就不会出现调用接口失败的情况出现了。这些注解无非也就是做这些工作的。下面列举......
  • springboot整合springSecurity入门案例(实现登录,记住我等常用标签使用)
    一,整合进依赖每个依赖都标了注释,大家可以按照自己需要的来添加,置于配置问件啥的,大家可以参考springboot+mybatisplus+redis整合(附上脚手架完整代码)<!--主要就是加了这个依赖--><dependency><groupId>org.springframework.security</groupId><artifact......
  • 各种情况下使用synchronized的差别
    这里不做原理分析,列举了7种情况,意在我们使用synchronized时更加有底气。下面的情况都是围绕这个姑且称为定理的东西来讲的synchronized作用于方法上,有static的修饰时锁定的是调用这个方法的对象无static修饰时锁定的是拥有这个方法的类的class情况1publicclasstest02{pub......
  • 序列化之@JsonComponent、@JsonInclude、@JsonSerialize、@JsonIgnore、JsonProperty
    前言:很多时候,例如前端需要字段user可能只是需要用到user中的userName属性,而后端传过去的却是一整个user对象,这样显然是不行的。那有没有一种技术,可以把后端传给前端的user类型的值改变为userName类型的值呢?@JsonComponent、@JsonInclude、@JsonSerialize可以在序列化的时候动手脚,可......
  • ConcurrentHashMap源码逐行解读基于jdk1.8
    前导知识//node数组最大容量:2^30=1073741824privatestaticfinalintMAXIMUM_CAPACITY=1<<30;//默认初始值,必须是2的幕数privatestaticfinalintDEFAULT_CAPACITY=16;//数组可能最大值,需要与toArray()相关方法关联st......