相关疑难解决方法(0)

大对象堆碎片

我正在研究的C#/ .NET应用程序正在遭受缓慢的内存泄漏.我已经使用CDB和SOS来尝试确定发生了什么,但数据似乎没有任何意义,所以我希望你们中的一个人之前可能已经经历过这种情况.

该应用程序在64位框架上运行.它不断地计算并将数据序列化到远程主机,并且正在大量地击中大对象堆(LOH).但是,我希望大多数LOH对象都是瞬态的:一旦计算完成并且已经发送到远程主机,就应该释放内存.然而,我所看到的是大量(实时)对象数组与空闲的内存块交织,例如,从LOH中获取一个随机段:

0:000> !DumpHeap 000000005b5b1000  000000006351da10
         Address               MT     Size
...
000000005d4f92e0 0000064280c7c970 16147872
000000005e45f880 00000000001661d0  1901752 Free
000000005e62fd38 00000642788d8ba8     1056       <--
000000005e630158 00000000001661d0  5988848 Free
000000005ebe6348 00000642788d8ba8     1056
000000005ebe6768 00000000001661d0  6481336 Free
000000005f214d20 00000642788d8ba8     1056
000000005f215140 00000000001661d0  7346016 Free
000000005f9168a0 00000642788d8ba8     1056
000000005f916cc0 00000000001661d0  7611648 Free
00000000600591c0 00000642788d8ba8     1056
00000000600595e0 00000000001661d0   264808 Free
...
Run Code Online (Sandbox Code Playgroud)

显然,如果我的应用程序在每次计算期间创建长寿命的大对象,我会期望这种情况.(它确实这样做,我接受会有一定程度的LOH碎片,但这不是问题.)问题是你可以在上面的转储中看到的非常小的(1056字节)对象数组,我在代码中看不到正在创建,并以某种方式保持根深蒂固.

另请注意,转储堆段时CDB不报告类型:我不确定这是否相关.如果我转储标记的(< - )对象,CDB/SOS报告正常:

0:015> !DumpObj 000000005e62fd38
Name: System.Object[]
MethodTable: 00000642788d8ba8
EEClass: 00000642789d7660
Size: 1056(0x420) bytes
Array: Rank 1, Number of elements 128, Type CLASS …
Run Code Online (Sandbox Code Playgroud)

.net c# memory-leaks memory-management windbg

96
推荐指数
2
解决办法
3万
查看次数

当仍有大量内存空闲时,抛出'System.OutOfMemoryException'

这是我的代码:

int size = 100000000;
double sizeInMegabytes = (size * 8.0) / 1024.0 / 1024.0; //762 mb
double[] randomNumbers = new double[size];
Run Code Online (Sandbox Code Playgroud)

例外:抛出了类型'System.OutOfMemoryException'的异常.

我在这台机器上有4GB内存当我开始运行时,2.5GB是免费的,PC上有足够的空间来处理762mb的100000000随机数.我需要在给定可用内存的情况下尽可能多地存储随机数.当我去生产时,盒子上将有12GB,我想要使用它.

CLR是否将我限制为默认的最大内存?以及如何申请更多?

更新

我认为将其分解为更小的块并逐渐增加我的内存需求将有助于如果问题是由于内存碎片,但它不会无法超过256mb的总ArrayList大小,无论我做什么调整blockSize.

private static IRandomGenerator rnd = new MersenneTwister();
private static IDistribution dist = new DiscreteNormalDistribution(1048576);
private static List<double> ndRandomNumbers = new List<double>();

private static void AddNDRandomNumbers(int numberOfRandomNumbers) {
    for (int i = 0; i < numberOfRandomNumbers; i++) {
      ndRandomNumbers.Add(dist.ICDF(rnd.nextUniform()));                
  }
}
Run Code Online (Sandbox Code Playgroud)

从我的主要方法:

int blockSize = 1000000;

while …
Run Code Online (Sandbox Code Playgroud)

c# memory-management out-of-memory

86
推荐指数
6
解决办法
25万
查看次数

为什么byte []的最大大小为2 GB - 57 B?

在我的64位机器上,这个C#代码有效:

new byte[2L * 1024 * 1024 * 1024 - 57]
Run Code Online (Sandbox Code Playgroud)

但是这个抛出一个OutOfMemoryException:

new byte[2L * 1024 * 1024 * 1024 - 56]
Run Code Online (Sandbox Code Playgroud)

为什么?

我知道托管对象的最大大小是2 GB,我正在创建的数组对象包含的内容超过了我想要的字节数.也就是说,同步块编号有4个字节(或8?),MethodTable参考有8个字节,数组大小有4个字节.这是24个字节,包括填充,所以为什么我不能分配一个2G-24字节的数组?最大尺寸真的 2 GB吗?如果是这样的话,2 GB的剩余部分用于什么?

注意:我实际上不需要分配一个包含200万字节的数组.即使我这样做,56个字节的开销可以忽略不计.我可以使用自定义轻松解决限制BigArray<T>.

.net arrays limits

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

.Net数组大小的局限性

我听说.Net的大小有一个严格的限制Array.有人说,可以分配给任何单个实例的最大内存量Array对象(无论它是int[],double[]或您自己的阵列)为2GB.不,如果你有64位机器,2GB限制仍然存在.

我不确定我的印象是否正确.有谁可以确认?

c# arrays

26
推荐指数
2
解决办法
2万
查看次数

在64位处理器上为3点结构分配了多少字节?

有一个问题:

鉴于:

struct Point {int x; int y;}
var p = new Point[3]
Run Code Online (Sandbox Code Playgroud)

如果我们使用64位处理器,将在堆栈和堆中分配多少字节的内存?

正确答案.Net44.有人可以解释这个数字是如何出现的吗?

据我所知,p将占用堆栈中的8个字节x64.

并且我们有Int32每个结构的两个值,因此 堆中的p.Length * sizeof(Point) 3*8 = 24个字节用于数组.

这将是32个字节.在这种情况下剩下的12个字节是多少?

.net c# memory arrays struct

24
推荐指数
2
解决办法
2246
查看次数

String和Char类型如何在.NET中存储在内存中?

我需要存储一个语言代码字符串,例如"en",它总是包含2个字符.

将类型定义为"String"或"Char"更好吗?

private string languageCode;
Run Code Online (Sandbox Code Playgroud)

VS

private char[] languageCode;
Run Code Online (Sandbox Code Playgroud)

或者还有另一种更好的选择吗?

这些2如何存储在内存中?分配值时,将为它们分配多少字节或位?

c# memory clr garbage-collection memory-management

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

我的(巨大的)应用程序抛出一个OutOfMemoryException,现在是什么?

这是迄今为止我构建的最复杂的软件,现在它似乎在某些时候耗尽了内存.我还没有进行过广泛的测试,因为我有点迷失了我应该如何解决手头的问题.

HandleCount: 277
NonpagedSystemMemorySize: 48136
PagedMemorySize: 1898590208
PagedSystemMemorySize: 189036
PeakPagedMemorySize: 1938321408
VirtualMemorySize: 2016473088
PeakVirtualMemory: 2053062656
WorkingSet: 177774592
PeakWorkingSet: 883834880
PrivateMemorySize: 1898590208
PriviligedProcessorTime: 00:00:15.8593750
UserProcessorTime: 00:00:01.6562500
TotalProcessorTime: 00:00:17.5156250
GDI Objects: 30
User Objects: 27
Run Code Online (Sandbox Code Playgroud)

我有一个自动化的全局异常捕获器,在异常时收集上述信息(使用System.Diagnostics.Process) - 以及异常信息,日志和屏幕截图 - 并通过电子邮件发送给我所有内容.

这已经很好地工作了,因为我已经能够根据电子邮件信息插入错误.到目前为止,这是.该软件有数万行,并使用托管和非托管资源.

我可以逐行开始编写代码,但有些我觉得这可能不是尝试推断内存构建问题的最佳方法.

由于我以前从未做过这种分析,你会如何建议解决这类问题?

.net c# memory profiling

6
推荐指数
3
解决办法
641
查看次数

C#List <double> size vs double [] size

所以我只是从微软测试CLR Profiler,我做了一个小程序,创建了一个包含1,000,000个双打的List.我检查了堆,结果列表<>大小大约是124KB(我不记得确切,但它就在那附近).这真的震撼了我的世界,如果它有100万双打怎么可能是124KB呢?无论如何,之后我决定检查双[1000000].令我惊讶的是(因为这是我所期望的List <> = P),因此数组大小为7.6MB.巨大的差异!!

他们怎么会不一样?List <>如何管理其项目(令人难以置信)内存效率?我的意思是,它不像其他7.5 mb在其他地方,因为在我创建了100万双打之后,应用程序的大小大约增加了3或4 KB.

.net c# arrays generic-list

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

数组元数据问题(缓存行)

有一些简单的代码

Int32[] tmpInt = new Int32[32];

            long lStart = DateTime.Now.Ticks;


            Thread t1 = new Thread(new ThreadStart(delegate()
            {
                for (Int32 i = 0; i < 100000000; i++)
                    Interlocked.Increment(ref tmpInt[5]);
            }));

            Thread t2 = new Thread(new ThreadStart(delegate()
            {
                for (Int32 i = 0; i < 100000000; i++)
                    Interlocked.Increment(ref tmpInt[20]);
            }));


            t1.Start();
            t2.Start();

            t1.Join();
            t2.Join();

            Console.WriteLine(((DateTime.Now.Ticks - lStart)/10000).ToString());
Run Code Online (Sandbox Code Playgroud)

我的核心2组合需要大约3秒钟.如果我将t1中的索引更改为tmpInt [4],则需要约5.5秒.

无论如何,第一个缓存行在索引4处结束.由于缓存行是64字节而5个int32只是20个字节,这意味着在实际数组之前有44个字节的元数据和/或填充.

我测试的另一组值,其中5和21.5和21需要~3秒,但5和20需要~5.5秒,但这是因为索引20与索引5共享相同的缓存行,因为它们在相同的间隔内64个字节.

所以我的问题是,.Net在数组之前预留了多少数据并且这个数量在32位和64位系统之间变化了吗?

谢谢 :-)

.net c#

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

我的类使用了多少内存实例 - 务实的答案

  1. 调用构造函数后,以下类的实例有多大?我想这通常可以写为 size = nx + c,其中 x86 中 x = 4,x64 中 x = 8。n = ? c = ?
  2. .NET 中是否有某种方法可以返回这个数字?

class Node { byte[][] a; int[] b; List<Node> c; public Node() { a = new byte[3][]; b = new int[3]; c = new List<Node>(0); } }

.net c# memory-management micro-optimization

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

数组在内存中的大小是多少?

我想知道阵列的大小.我想到size * sizeof(item) + sizeof(pointer)但是为了能够引用数组而分配了多少字节?

c# arrays

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