博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
.net垃圾回收学习【C#中的Stack和heap]【续1】
阅读量:4980 次
发布时间:2019-06-12

本文共 1919 字,大约阅读时间需要 6 分钟。

From: 

学习加记录。

        本部分主要讲Pointer基本概念。

Parameters,  the Big Picture

         当我们调用一个方法的时候,会发生如下情况:

  • 为在Stack上执行的方法所需要的信息分配空间(called stack frame). 包括正在运行的函数的调用地址(calling address)。调用地址(call address)是一个指针,一般是一个GoTo的指令,起作用是当线程完成方法调用后能够知道返回到何处以便能够继续执行。
  • 将要调用的方法的参数复制到Stack上。  
  • 控制权转移到了编译过的要调用的方法上,线程开始执行要调用的方法的代码,因此我们Call Stack上有了当前调用方法的stack frame。

代码如下:

public int AddFile(int pValue)
{
int result;
result = pValue + 5;
return result;
}
 

NOTE : the method does not live on the stack, and is illustrated here just for reference as the beginnnig of the stack frame.

         关于放到Stack上的参数依据是值类型还是引用类型来处理,值类型是直接复制,引用类型则是复制相关的指针。

passing Value Type

          当我们传递一个值类型的时候,在Stack上会分配出来一段相应的空间,我们的值类型会被复制到Stack上刚刚分配的空间上。看如下代码:

class Class1
{
public void Go(){
int x = 5;
AddFive(x);
Console.WriteLine(x.ToString())
}
 
public  int AddFive(int pValue)
{
pValue += 5;
return pValue;
}
}
当GO方法执行的时候,变量”x”在Stack上被分配了一个空间,并且把值5赋值到新的空间上。如下图:
 
然后, AddFive()方法被放到Stack上,同时它的参数也被创建,参数的值也被从变量”X”复制过来.
当addFive()方法执行完毕后,调用堆栈回到了Go()上,因为方法AddFive()执行完毕了,值pValue自然而然的被移除了。如下图:
 

所以,很容易理解输出结果为什么是5了吧。关键点是任何传递给方法的值类型参数都是副本复制(carbon copy), 原始值被保留了下来。

另外一件需要注意的事情是:如果我们有很大的值类型数据,比如说比较大的Struct,当他被传递个Stack的时候,每次都会消耗很多的Cpu和内存空间在Stack上。当Stack没有足够多的空间的时候,就会溢出。Struct是一个可以很大的值类型数据,当我们处理他的时候需要小心。

这里有一个比较大的Struct:

public struct MyStruct
{
long a,b,c,d,e,f,g,h,i,j,k,l,m,n;
 
}

让我们看看当我们执行如下代码的时候会发生什么事情:

public void Go()
{
MyStruct x = new MyStruct();
DoSomething(x);
}

public void DoSomething(MyStruct pValue)
{
}

这样的话会十分的没有效率。想想一下如果MyStruct被传递了上千次将会导致什么样的后果?那我们怎么避免这种问题的出现呢?只需要将最初的值传递改为方法传递即可。

public void Go()
 
{
 
MyStruct x = new MyStruct();
 
DoSomething(ref x);
 
}
 
public struct MyStruct
{
 
long a, b, c, d, e, f, g, h, i, j, k, l, m;
 
}
public void DoSomething(ref MyStruct pValue)
 
{
 
// DO SOMETHING HERE....
 
}

这种方式能够使得我们的内存使用更加的有效率。

需要注意的是:当我们通过引用传递的时候,我们是传递的变量所在的地址,修改的也是变量所在的地址。

Passing Reference Types

转载于:https://www.cnblogs.com/sunshinefly128/archive/2011/08/21/2147710.html

你可能感兴趣的文章
关于【最短路径】
查看>>
PostgreSQL10.5安装详细步骤(Win10)
查看>>
Linux运维正则表达式之awk
查看>>
SpringMVC拦截器实现:当用户访问网站资源时,监听session是否过期
查看>>
PHP导出数据到CSV文件
查看>>
POJ - 3693 Maximum repetition substring (后缀数组)
查看>>
Ghost Win10系统X64位和32位10041装机版下载
查看>>
App跳转至系统Settings
查看>>
RabbitMQ
查看>>
参数传递 引用传递 值传递 ref传递
查看>>
spring ehcache使用笔记
查看>>
【知识总结】多项式全家桶(三点五)(拆系数解决任意模数多项式卷积)
查看>>
HTML5中input文本框输入,h1标签实时输出代码
查看>>
MySQL数据类型
查看>>
WPF 带水印的密码输入框
查看>>
ASP.NET Core 2.2 基础知识(十一) ASP.NET Core 模块
查看>>
ASP.NET Core 运行原理解剖[4]:进入HttpContext的世界
查看>>
sql-----STR 函数
查看>>
WPF中类似使用tab键功能,可以向上向下定位
查看>>
设置WPF输入框焦点
查看>>