gpt4 book ai didi

c# - 程序员真的应该关心在 .NET 中创建对象的数量和/或频率吗?

转载 作者:IT王子 更新时间:2023-10-28 23:32:21 24 4
gpt4 key购买 nike

这个问题困扰我很久了。我来自一个沉重而漫长的 C++ 背景,自从我开始用 C# 编程和处理垃圾收集以来,我一直觉得这种“魔法”是有代价的。

我最近开始从事一个用 Java(服务器端)编写的大型 MMO 项目。我的主要任务是优化内存消耗和 CPU 使用率。每秒发送数十万条消息,并创建相同数量的对象。经过大量分析后,我们发现 VM 垃圾收集器正在消耗大量 CPU 时间(由于不断的收集),并决定尝试尽量减少对象创建,在适用的情况下使用池并重用我们所能做的一切。到目前为止,这已被证明是一个非常好的优化。

所以,据我所知,拥有一个垃圾收集器很棒,但你不能只是假装它不存在,你仍然需要注意对象的创建及其含义(至少在 Java 中)以及像这样的大型应用程序)。

那么,对于 .NET 也是如此吗?如果是,到什么程度?

我经常编写这样的函数对:

// Combines two envelopes and the result is stored in a new envelope.
public static Envelope Combine( Envelope a, Envelope b )
{
var envelope = new Envelope( _a.Length, 0, 1, 1 );
Combine( _a, _b, _operation, envelope );
return envelope;
}

// Combines two envelopes and the result is 'written' to the specified envelope
public static void Combine( Envelope a, Envelope b, Envelope result )
{
result.Clear();
...
}

提供了第二个功能,以防有人已经制作了可以重复使用来存储结果的信封,但我觉得这有点奇怪。

当我宁愿使用类时,我有时也会编写结构,只是因为我知道会不断创建和处置数以万计的实例,这对我来说真的很奇怪。

我知道作为 .NET 开发人员我不应该担心这类问题,但我对 Java 的经验和常识告诉我应该这样做。

非常感谢您对此事的任何看法和想法。提前致谢。

最佳答案

是的,.NET 也是如此。我们大多数人都可以忽略内存管理的细节,但在您的情况下——或者在高容量导致内存拥塞的情况下——则需要进行一些优化。

您可能会考虑针对您的案例进行优化——实际上,我一直在考虑写一篇关于此的文章——是结构体和 ref 的组合,以实现真正的确定性处理。

由于您来自 C++ 背景,您知道在 C++ 中您可以在堆上(使用 new 关键字并返回一个指针)或在堆栈上(通过像原始类型一样实例化它,即MyType myType;)。您可以通过告诉函数接受引用(在声明中的参数名称之前使用 & 关键字)来通过引用函数和方法来传递堆栈分配的项。只要分配对象的方法仍在范围内,这样做就会将堆栈分配的对象保留在内存中;一旦超出范围,对象就会被回收,析构函数被调用,ba-da-bing, ba-da-boom, Bob's yer Uncle,所有这些都在没有指针的情况下完成。

在我的 C++ 时代,我使用该技巧创建了一些性能惊人的代码——当然,代价是更大的堆栈和堆栈溢出的风险,但仔分割析设法将这种风险降至最低。

我的意思是,您可以在 C# 中使用 structs 和 refs 来做同样的事情。权衡?如果您不小心或使用大型对象,除了堆栈溢出的风险之外,您还被限制为没有继承,并且您的代码紧密耦合,使其可测试性和可维护性降低。此外,每当您使用核心库调用时,您仍然必须处理问题。

不过,您的情况可能值得一看。

关于c# - 程序员真的应该关心在 .NET 中创建对象的数量和/或频率吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1132077/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com