6
|
stakx - no longer contributing Saravana Kumar · 技术社区 · 14 年前 |
![]() |
1
11
你接受的答案是错误的。
值类型的特征是它们的传递值语义,但这并不意味着它们实际上是由生成的机器代码复制的。 例如,对复数进行平方的函数可以接受两个浮点寄存器中的实部和虚部分量,并将其结果返回到两个浮点寄存器中。代码生成器优化了所有的复制。 有几个人在下面的评论中解释了为什么这个答案是错误的,但一些主持人删除了所有答案。
这完全是胡说八道。GC只看到运行时可用的信息,到那时,范围的所有概念都消失了。“一旦超出范围”,GC将不会收集任何东西。GC将在无法访问之后的某个时间点收集它。
再说一次,这完全是胡说八道。在值类型中具有引用没有任何错误。 现在,要回答您的问题:
值类型当然不会“只存在于评估堆栈上”。首选是将它们存储在寄存器中。如有必要,它们将溢出到堆栈中。有时它们甚至被放在一堆箱子里。
例如,如果编写一个循环数组元素的函数,那么
另一个不存在于堆栈中的值类型的重要示例是,当使用具有值类型元素的数组时。特别地,
the .NET
CIL是一种高级的中间语言,因此,它不会向您提供关于寄存器分配和溢出到堆栈的任何信息,甚至不会向您提供装箱的准确图片。然而,查看CIL可以让您了解前端C或F编译器如何将一些值类型框起来,因为它可以将更高级的构造(如异步和理解)转换为CIL。 关于垃圾收集的更多信息,我强烈建议 The Garbage Collection Handbook 和 The Memory Managment Reference . 如果您希望深入了解vms中值类型的内部实现,那么我建议您阅读自己的源代码。 HLVM project . 在HLVM中,元组是值类型,您可以看到所生成的汇编程序,以及它如何使用LLVM尽可能将值类型的字段保存在寄存器中,并优化消除不必要的复制,仅在必要时溢出到堆栈。 |
![]() |
2
5
请考虑以下事项:
值类型是 典型地 在堆栈上分配,引用类型为 典型地 在堆上分配,但这实际上不是.NET规范的一部分,并且不能保证(在第一个链接的日志中,Eric甚至指出了一些明显的异常)。 更重要的是,假设堆栈通常比堆便宜是不正确的 自动地 意味着任何使用堆栈语义的程序或算法都将比GC管理的堆运行得更快或更高效。 There a number of papers written on this topic 而且,对于一个GC堆来说,它完全有可能并且经常比具有大量对象的堆栈分配更出色,因为现代GC实现实际上对 不要 需要释放(而不是完全固定到堆栈上对象数量的堆栈实现)。 换句话说,如果您已经分配了数千或数百万个临时对象-甚至 如果 关于具有堆栈语义的值类型的假设在特定环境中的特定平台上是正确的-利用它 仍然会使程序变慢! 因此,我将返回到我最初的建议:让GC完成它的工作,并且不要假定在所有可能的执行条件下,如果没有完整的性能分析,您的实现就可以胜过它。如果您从干净的、可维护的代码开始,您可以在以后进行优化;但是如果您以可维护性为代价编写您认为是性能优化的代码,并且在以后的性能假设中被证明是错误的,那么您的项目在维护开销、缺陷计数等方面的成本会大得多。 |
![]() |
3
4
它是一个JIT编译器实现细节,用于分配.locals。现在,我不知道有什么东西不能在堆栈帧上分配它们。通过调整堆栈指针来“分配”它们,通过重新设置堆栈指针来“释放”它们。很快,很难改进。但谁知道呢,20年后,我们可能都在运行带有CPU核心的机器,这些核心经过优化,只运行带有完全不同的内部实现的托管代码。JIT优化器可能以大量寄存器为核心,现在已经使用寄存器来存储局部变量。 临时性由C编译器发出,以在对象初始值设定项引发异常时提供一些最低一致性保证。它防止代码在catch或finally块中看到部分初始化的对象。也用于using和lock语句中,如果您替换代码中的对象引用,它可以防止错误的对象被释放或解锁。 |
![]() |
4
1
结构是值类型,用于局部变量时在堆栈上分配。但如果将局部变量强制转换为
结果,结构在超出作用域后被释放,此外,它们被装箱并移动到堆中,之后垃圾收集器将负责在不再引用对象时释放它们。 我不确定所有编译器生成的局部变量的原因,但我假定它们被使用是因为您使用了对象初始值设定项。首先使用编译器生成的局部变量初始化对象,并且仅在复制到局部变量的对象初始值设定项完全执行之后。这样可以确保永远不会看到只执行了一些对象初始值设定项的实例。 |
![]() |
TheKing · 为什么数组的地址可以有负值? 2 年前 |
![]() |
yurnero · MATLAB:“加载”一个快速访问功能 6 年前 |
![]() |
joe · 一页可以同时在两个工作集中吗? 6 年前 |
![]() |
Jaques · “.exe”已触发断点 6 年前 |
![]() |
adn bps · 在函数中修改变量的高效内存方法 6 年前 |
![]() |
Gauraang Khurana · C语言中分段错误的不稳定行为 6 年前 |
![]() |
Rajesh K · 如何查找设备中存在的广告垃圾? 6 年前 |