使用 ref 传递引用类型是否节省内存?

2023-11-21

在 C# 中,方法的参数可以是引用类型或值类型。传递引用类型时,会传递引用的副本。这样,如果在方法内部我们尝试将传递的引用重新分配给另一个对象实例,则在方法外部重新分配是不可见的。

为了使其正常工作,C# 有 ref 修饰符。使用 ref 传递引用类型实际上使用原始引用而不是副本。 (如我错了请纠正我)。

在这种情况下,由于我们没有创建引用的副本,所以我们是否节省了内存?如果广泛调用某个方法,这是否会提高应用程序的整体性能?

Thanks!


Claim

不,事实并非如此。如果有的话,那就是由于额外的查找而变慢了。

There's 没有理由通过引用传递引用类型,除非您专门打算稍后分配给它。


Proof

由于有些人似乎认为编译器传递“变量itself”,看一下这段代码的反汇编:

using System;

static class Program
{
    static void Test(ref object o) { GC.KeepAlive(o); }

    static void Main(string[] args)
    {
        object temp = args;
        Test(ref temp);
    }
}

这是(为了简单起见,在 x86 上):

// Main():
// Set up the stack
00000000  push        ebp                    // Save the base pointer
00000001  mov         ebp,esp                // Set up stack pointer
00000003  sub         esp,8                  // Reserve space for local variables
00000006  xor         eax,eax                // Zero out the EAX register

// Copy the object reference to the local variable `temp` (I /think/)
00000008  mov         dword ptr [ebp-4],eax  // Copy its content to memory (temp)
0000000b  mov         dword ptr [ebp-8],ecx  // Copy ECX (where'd it come from??)
0000000e  cmp         dword ptr ds:[00318D5Ch],0  // Compare this against zero
00000015  je          0000001C               // Jump if it was null (?)
00000017  call        6F910029               // (Calls some internal method, idk)

// THIS is where our code finally starts running
0000001c  mov         eax,dword ptr [ebp-8]  // Copy the reference to register
0000001f  mov         dword ptr [ebp-4],eax  // ** COPY it AGAIN to memory
00000022  lea         ecx,[ebp-4]            // ** Take the ADDRESS of the copy
00000025  call        dword ptr ds:[00319734h] // Call the method

// We're done with the call
0000002b  nop                                // Do nothing (breakpoint helper)
0000002c  mov         esp,ebp                // Restore stack
0000002e  pop         ebp                    // Epilogue
0000002f  ret                                // Return

这是来自一个优化代码的编译。显然,传递的是变量的地址,而不是“变量本身”。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 ref 传递引用类型是否节省内存? 的相关文章

  • 查找c中结构元素的偏移量

    struct a struct b int i float j x struct c int k float l y z 谁能解释一下如何找到偏移量int k这样我们就可以找到地址int i Use offsetof 找到从开始处的偏移量z
  • Asp.NET WebApi 中类似文件名称的路由

    是否可以在 ASP NET Web API 路由配置中添加一条路由 以允许处理看起来有点像文件名的 URL 我尝试添加以下条目WebApiConfig Register 但这不起作用 使用 URIapi foo 0de7ebfa 3a55
  • 嵌套接口:将 IDictionary> 转换为 IDictionary>?

    我认为投射一个相当简单IDictionary
  • 类模板参数推导 - clang 和 gcc 不同

    下面的代码使用 gcc 编译 但不使用 clang 编译 https godbolt org z ttqGuL template
  • BitTorrent 追踪器宣布问题

    我花了一点业余时间编写 BitTorrent 客户端 主要是出于好奇 但部分是出于提高我的 C 技能的愿望 我一直在使用理论维基 http wiki theory org BitTorrentSpecification作为我的向导 我已经建
  • 如何使用 ICU 解析汉字数字字符?

    我正在编写一个使用 ICU 来解析由汉字数字字符组成的 Unicode 字符串的函数 并希望返回该字符串的整数值 五 gt 5 三十一 gt 31 五千九百七十二 gt 5972 我将区域设置设置为 Locale getJapan 并使用
  • HTTPWebResponse 响应字符串被截断

    应用程序正在与 REST 服务通信 Fiddler 显示作为 Apps 响应传入的完整良好 XML 响应 该应用程序位于法属波利尼西亚 在新西兰也有一个相同的副本 因此主要嫌疑人似乎在编码 但我们已经检查过 但空手而归 查看流读取器的输出字
  • 堆栈溢出:堆栈空间中重复的临时分配?

    struct MemBlock char mem 1024 MemBlock operator const MemBlock b const return MemBlock global void foo int step 0 if ste
  • 带动态元素的 WPF 启动屏幕。如何?

    我是 WPF 新手 我需要一些帮助 我有一个加载缓慢的 WPF 应用程序 因此我显示启动屏幕作为权宜之计 但是 我希望能够在每次运行时更改屏幕 并在文本区域中显示不同的引言 这是一个生产力应用程序 所以我将使用非愚蠢但激励性的引言 当然 如
  • 将多个表映射到实体框架中的单个实体类

    我正在开发一个旧数据库 该数据库有 2 个具有 1 1 关系的表 目前 我为每个定义的表定义了一种类型 1Test 1Result 我想将这些特定的表合并到一个类中 当前的类型如下所示 public class Result public
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • SolrNet连接说明

    为什么 SolrNet 连接的容器保持静态 这是一个非常大的错误 因为当我们在应用程序中向应用程序发送异步请求时 SolrNet 会表现异常 在 SolrNet 中如何避免这个问题 class P static void M string
  • 什么时候虚拟继承是一个好的设计? [复制]

    这个问题在这里已经有答案了 EDIT3 请务必在回答之前清楚地了解我要问的内容 有 EDIT2 和很多评论 有 或曾经 有很多答案清楚地表明了对问题的误解 我知道这也是我的错 对此感到抱歉 嗨 我查看了有关虚拟继承的问题 class B p
  • 如何查看网络连接状态是否发生变化?

    我正在编写一个应用程序 用于检查计算机是否连接到某个特定网络 并为我们的用户带来一些魔力 该应用程序将在后台运行并执行检查是否用户请求 托盘中的菜单 我还希望应用程序能够自动检查用户是否从有线更改为无线 或者断开连接并连接到新网络 并执行魔
  • 使用 x509 证书签署 json 文档或字符串

    如何使用 x509 证书签署 json 文档或字符串 public static void fund string filePath C Users VIKAS Desktop Data xml Read the file XmlDocum
  • 向现有 TCP 和 UDP 代码添加 SSL 支持?

    这是我的问题 现在我有一个 Linux 服务器应用程序 使用 C gcc 编写 它与 Windows C 客户端应用程序 Visual Studio 9 Qt 4 5 进行通信 是什么very在不完全破坏现有协议的情况下向双方添加 SSL
  • 将控制台重定向到 .NET 程序中的字符串

    如何重定向写入控制台的任何内容以写入字符串 对于您自己的流程 Console SetOut http msdn microsoft com en us library system console setout aspx并将其重定向到构建在
  • 基于 OpenCV 边缘的物体检测 C++

    我有一个应用程序 我必须检测场景中某些项目的存在 这些项目可以旋转并稍微缩放 更大或更小 我尝试过使用关键点检测器 但它们不够快且不够准确 因此 我决定首先使用 Canny 或更快的边缘检测算法 检测模板和搜索区域中的边缘 然后匹配边缘以查
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • C++ 标准是否指定了编译器的 STL 实现细节?

    在写答案时this https stackoverflow com questions 30909296 can you put a pimpl class inside a vector我遇到了一个有趣的情况 这个问题演示了这样一种情况

随机推荐

  • 为什么 substring() 方法 substring(start_index(inclusive), end_index(exclusive)) [关闭]

    Closed 这个问题是基于意见的 目前不接受答案 为什么子字符串将起始参数作为索引 第二个参数作为从开头开始的长度 换句话说 1 2 3 4 5 lt Length from beginning A B C D E 0 1 2 3 4 l
  • 后台线程如何挂起UI线程?

    我正在使用后台线程通过 USB 初始化仪器 当我尝试打开设备时 用户界面挂起 我希望后台线程在设备上调用 Open 时暂停 但 UI 线程不会 我正在测试这个 没有来自后台线程的 UI 交互 我不知道如何调试这个问题 而且这个问题太宽泛了
  • 如何从C中的stdout读取

    我需要写一个C程序 myprogram 检查其他程序的输出 它基本上应该像这样工作 otherprogram myprogram 但我找不到如何逐行读取stdout 或管道 然后将所有这些写入stdout 一个程序的stdout成为下一个程
  • numpy 对数组进行切片而不复制它

    我的矩阵中有大量数据x我需要分析一些子矩阵 我使用以下代码来选择子矩阵 gt gt gt import numpy as np gt gt gt x np random normal 0 1 20 2 gt gt gt x array 1
  • Matlab 上的图像去模糊

    我是 MatLab 新手 一直在玩并阅读帮助指南 但我似乎无法解决这种情况 我用高斯算法去除了噪音 这是成功的 但我没有设法让图像变得清晰 我尝试使用理查森 露西去模糊算法 但它不起作用 知道如何解决这个问题吗 提前谢谢 这是我到目前为止所
  • C# HttpWebResponse 彗星问题

    我想知道如何读取 HttpWebRequest 和 HttpWebResponse 的持久连接 问题似乎是 GetResponseStream 函数在返回之前等待服务器连接关闭 有没有其他简单的方法来读取彗星连接 不起作用的例子 get t
  • Google Cloud Functions:如何共享源代码?

    我有一个节点服务器和多个控制器 它们在该目录中执行数据库操作和帮助程序 例如 用于电子邮件 我想在我的函数中使用该目录中的源代码 假设以下目录结构 src server app controllers email helper js fns
  • 1 和 0 的数量相等的最大子矩阵

    给定一个大小矩阵mxn仅包含 0 和 1 我需要找到其中 1 和 0 的数量相等的最大子矩阵 蛮力方法是O m 2 n 2 我们还能做得更好吗 我尝试应用动态规划 但找不到任何最佳的子结构 我相信这里讨论了这个问题的类似一维版本 用于查找最
  • REST api,具有关系的 POST 实体?

    我遇到一个问题 我无法决定如何继续处理这个问题 我需要知道是否有任何标准方法来解决这个问题 或者你们是否对这个问题有任何很好的意见 问题是我已经开始构建一个非常基本的 API 来用于学习目的 API 是一个简单的音乐商店 该商店有一些需要艺
  • 根据 C89 标准,字符串文字的修改是否为未定义行为?

    我相信在 C99 中 字符串文字的修改是未定义的行为 我没有该标准的副本 但我有一份 C1X n1570 草案 其中在 6 4 5 第 7 段中规定 未指定这些数组是否不同 前提是它们的元素具有 适当的值 如果程序尝试修改这样的数组 则行为
  • 使用 DPAPI 时安全存储可选熵

    所以我尝试使用 DPAPI 存储对称密钥 一切都很好 但是如何处理熵呢 这回答了问题here确实没有提供足够的洞察力 这看起来像是一个滑坡 我可以使用机器商店来存储熵 但又是什么阻止了人们获得这一点呢 注意 我使用用户范围存储当前密钥 所以
  • 以设计形式或用户控制进行自定义处置

    我创建了一个自定义 WinForms UserControl 并希望覆盖 Dispose 然而 设计生成的代码已经包含一个 Dispose 方法 如何向我的组件添加自定义清理代码 您可以将 Dispose 方法从代码生成的文件移动到控件 c
  • WordPress 自定义表或自定义帖子类型?

    我正在使用 WordPress 制作一个包含职位发布的网站 我想知道存储公司详细信息的最佳方法 因为每个职位发布都必须链接到一家公司 通常情况下 我会在数据库中建立一个公司表 并在每个职位中放入公司 ID 然后加入以获取公司详细信息 然而
  • HTML 锚链接 - href 和 onclick 两者?

    我想编写一个锚标记来执行一些 JavaScript 然后继续执行href正在接受它 调用一个执行我的 JavaScript 的函数 然后设置window location or top location to the href位置不适合我
  • 在 GitHub Pages 上显示交互式绘图图表(.html 文件)

    我创建了以下情节 import plotly labels Oxygen Hydrogen Carbon Dioxide Nitrogen values 4500 2500 1053 500 trace plotly graph objs
  • 如何将 XCTest 依赖关系链接到生产/主要目标?

    我正在尝试用 Swift 编写 XCTest 框架的扩展 为此 我创建了一个具有两个目标的项目 主 生产目标和测试目标 当我正在为 XCTest 编写扩展时 我还需要在我的主 生产目标中导入 XCTest 但是 我很难这样做 当我在 Xco
  • 什么是模拟?

    什么是模拟 序言 如果你查一下名词mock在字典中你会发现这个词的定义之一是仿制品 模拟主要用于单元测试 被测对象可能依赖于其他 复杂 对象 为了隔离要测试的对象的行为 您可以用模拟真实对象行为的模拟来替换其他对象 如果真实对象无法合并到单
  • NodeJS/express - 公共 API 端点的安全性

    我正在开发基于 NodeJs Express 的网站项目 对于某些 UI 部分 我使用 Jquery ajax 请求来获取辅助数据 我们如何处理浏览器用于 ajax 调用的 Rest API 端点的一些基本控制 我正在考虑某种令牌授权 但一
  • 下载自定义文件时 file.download 出错

    我正在尝试从此网址下载 zip 文件 url1 lt http www clinicaltrials gov ct2 results cond 22acne 22 studyxml true 这是我的代码 tempZip lt tempfi
  • 使用 ref 传递引用类型是否节省内存?

    在 C 中 方法的参数可以是引用类型或值类型 传递引用类型时 会传递引用的副本 这样 如果在方法内部我们尝试将传递的引用重新分配给另一个对象实例 则在方法外部重新分配是不可见的 为了使其正常工作 C 有 ref 修饰符 使用 ref 传递引