小编Mih*_*ert的帖子

“AnyCPU”平台目标上的内存分配模式

我故意在一个简单的 C# 程序中泄漏内存,以了解有关 .NET 如何管理这方面的更多信息。这是使用int[]数组完成的,每个数组的大小为 1000 万,每 100 毫秒声明一次。数组的元素不会被“触及”(如分配一个值),以免将数据带入进程的工作集中:

const int BlockSIZE = 10000000;  // 10 million
const int noOfBlocks = 500;
int[][] intArray = new int[noOfBlocks][];

for (int k = 0; k < noOfBlocks; k++) {
    intArray[k] = new int[BlockSIZE];
    Console.WriteLine("Allocated (but not touched) for array {0}: {1} bytes", k, BlockSIZE);
    System.Threading.Thread.Sleep(100);
}
Run Code Online (Sandbox Code Playgroud)

我正在使用 VMMap(Mark Russinovich 构建的工具)来查看内存是如何分配的。该版本是最新版本(3.25,2018 年发布),因此它了解托管堆。

在具有 8 GB RAM 的 x64 Windows 10 计算机上使用 Visual Studio 2015 来编译和生成文件.exe。根据Platform target项目“构建”部分中的设置,可以看到与如何分配内存相关的不同结果,如下所示。

当 …

.net c# memory

7
推荐指数
1
解决办法
1051
查看次数

C#System.String实例是否真的在堆上结束?

让我们考虑一些非常简单的C#代码:

static void Main(string[] args)
        {
            int i = 5;
            string s = "ABC";
            bool b = false;
        }
Run Code Online (Sandbox Code Playgroud)

Jeffrey Richter的“ 通过C#进行CLR ”(第14章)指出,“ String类型是直接从Object派生的,使其成为引用类型,因此,String对象(其字符数组)始终存在于堆中,而不是在线程的堆叠 ”。

在书中的一个示例上也与上面的示例非常相似,它也涉及字符串:“ newobj IL指令构造了一个对象的新实例。但是,IL代码示例中没有newobj指令出现。相反,您看到了特殊的ldstr (负载字符串)IL指令,其通过使用从元数据得到的文字串构成一个字符串对象。这显示了公共语言运行库(CLR)不,事实上,具有构造文字串对象的一种特殊的方式。

查看IL代码,显然是这种情况(仅显示了相关部分):

[...]
    .locals init (
        [0] int32,
        [1] string,
        [2] bool
    )
    // (no C# code)
    IL_0000: nop
    // int num = 5;
    IL_0001: ldc.i4.5
    IL_0002: stloc.0
    // string text = "ABC";
    IL_0003: ldstr "ABC"
    IL_0008: stloc.1
    // bool flag = false;
[...]
Run Code Online (Sandbox Code Playgroud)

所述ldstrIL指令确保了的对象引用的字符串被压入堆栈 ”。这很有意义-字符串的实例保留在堆上,并且对该对象(其地址)的引用由变量存储在堆栈上。 …

c# stack cil heap-memory .net-assembly

7
推荐指数
0
解决办法
164
查看次数

将“任何 CPU/首选 32 位”作为 VS 中的默认构建设置的基本原理

假设在 x64 Windows 机器上使用最新版本的 Visual Studio 和 C# 并分配大量数据。

果然,在使用默认构建设置(如下图为 VS 2019 Preview 2.1)进行编译时,当您的进程达到 4 GB 时,您将耗尽用户虚拟地址空间。这是意料之中的,这里讨论了原因。

在此处输入图片说明

例如,分配本身可以通过创建几百个简单数组来完成,每个数组包含几百万个int元素。

我想了解的是为什么Any CPU/Prefer 32-bit选择 被选为默认构建选项。我也注意到,2015年VS具有相同的默认设置过了,最有可能的每一个出来,因为VS 11,如所描述的版本在这里

通常被问到的问题是“什么是 AnyCPU...?” 并且已经反复回答(1 2 3 4 5),对定位的优点简要地接触x86/ x64/ Any CPU + Prefer 32-bit。但我还没有找到一个明确的答案,为什么被Any CPU + Prefer 32-bit选为 VS 中的默认设置。

查看默认情况下反对为 x64 构建的原因:

  • x64 进程将使用更多内存:对于上面描述的简单示例(数组的数组int),实际情况并非如此。当然,对数组本身的引用将是双倍的(8 个字节而不是 4 个字节),但仅此而已。根据“Windows Internals”一书(内存管理章节),页表结构本身的 PFN 条目在 x86 和 x64 架构上都是 64 位宽,只是有 3 …

.net c# memory visual-studio

6
推荐指数
0
解决办法
786
查看次数

Azure Functions 中的高内存占用

我在 .NET Core 上使用一些简单的 C# 代码来查看 Azure Functions 的执行情况。

\n\n

用例是这样的:将 1000 万个 int 值添加到 ArrayList 作为 Azure 函数的一部分,并使用设置为 1 分钟的时间触发器来调用该函数。(我知道 ArrayList 已过时,不再使用,但我只是使用它来在堆上分配大量空间)。\n因此该函数的 C# 代码是这样的:

\n\n
using System.Collections;\n\npublic static void Run(TimerInfo myTimer, ILogger log)\n{\n    ArrayList numbers = new ArrayList();\n    Random random = new Random(1);\n    int noNumbers = 10000000;\n    for(int i=0;i<noNumbers;i++) {\n        numbers.Add(random.Next(10));\n    }\n\n    log.LogInformation($"Created an ArrayList of {numbers.Count} elements");\n    log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我检查了平台设置,发现这是 32 位的(我假设这是指 .NET Core 运行时为 32 位):

\n\n

在此输入图像描述

\n\n

在“桌面”环境中运行相同的示例代码,针对 …

c# memory azure azure-functions

5
推荐指数
0
解决办法
2434
查看次数

如何遍历多个AWS账户?

考虑一个拥有 50 多个账户的 AWS 组织。每个账户都创建了一个角色,允许对 EC2 服务进行只读访问(名为“EC2ReadAccess”),并与主(/管理)账户建立信任关系。主账户中的单个 IAM 用户应用了一个策略,允许其在每个账户中担任该角色。

我希望能够使用唯一的 IAM 用户迭代所有帐户,以便检索所有 EC2 实例。我知道同时对所有帐户运行 CLI 命令是不可能的。撇开循环遍历每个账户中的区域不谈,这已经被广泛讨论了是否有一个优雅的解决方案来做到这一点?

我想到的一个技巧是以编程方式构建文件credentials,以便它包含每个帐户的配置文件。每个配置文件依次“链接”到 IAM 用户的配置文件(如此处所述,并为每个条目更新角色内的账户 ID。下面是一个例子:

[user1]
aws_access_key_id=<key_id>
aws_secret_access_key=<secret_key>

[marketing]
role_arn = arn:aws:iam::123456789012:role/EC2ReadAccess
source_profile = user1
[dev]
role_arn = arn:aws:iam::234567890123:role/EC2ReadAccess
source_profile = user1
...
[prod]
role_arn = arn:aws:iam::345678901234:role/EC2ReadAccess
source_profile = user1
Run Code Online (Sandbox Code Playgroud)

运行 CLI 命令(在本例中aws ec2 describe-instances)可以附带--profile参数,以便循环显示credentials文件中存在的所有配置文件。该区域可以在另一个循环中循环。因此,预先以编程方式生成的要发出的命令列表可能类似于:

aws ec2 describe-instances --profile marketing --region us-east-1
aws ec2 describe-instances --profile marketing --region us-east-2
... …
Run Code Online (Sandbox Code Playgroud)

amazon-ec2 amazon-web-services

1
推荐指数
1
解决办法
2178
查看次数