首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

69f38ba4 1 72 System.ExecutionEngineException

2011-12-11 
关于C#内存占用的问题!从几道ACM题中发现的一个问题!问题是从http://acm.timus.ru 上的几道题开始的(1220,

关于C#内存占用的问题!从几道ACM题中发现的一个问题!
问题是从http://acm.timus.ru 上的几道题开始的(1220,1275,1306)

http://acm.timus.ru/problem.aspx?space=1&num=1220
http://acm.timus.ru/problem.aspx?space=1&num=1306

这3道题都是不推荐用Java或C#来解的,主要是内存限制的比较严,用c或pascal解,都存在内存使用超标的可能。
需要严谨的计算内存使用,并设计更为精巧的数据结构,才能通过这3道题的test。

可偏有不信邪的高手,于是一个名为Fyodor Menshikov的人出现,他用Java过了1220和1306。(这个人确实有点牛)

于是有几个象我这样常用C#的看到了希望,开始在这几道题上前仆后继,几天前1306的第一个c#方案出现了,是空军同志解的。
自己写了一个c#版的优先队列,确实很不错!受了他的鼓舞,我也用c#过了1306,方法也是大同小异。

在这3道题中,1306应当算是最容易的,给的空间较大,1220就要难不少,而1275比1220又要难上很多,连那个Fyodor Menshikov,
也没能用Java过。

在1306被搞定之后,大家又开始攻克1220,在AC1220的过程中,问题出现了。我做了如下的测试:

C# code
using System;namespace ConsoleApplication2{    class Program    {        static void Main()        {        }    }}


一个这样的程序,占用内存为365K,而一个这样的程序占用内存竟然骤增到405K

C# code
using System;namespace ConsoleApplication2{    class Program    {        static void Main()        {            int[] m = new int[100];        }    }}


这样的程序竟然只占409k

C# code
using System;namespace ConsoleApplication2{    class Program    {        static void Main()        {            int[] m = new int[100000];        }    }}


可是现在却变成了853K

C# code
using System;namespace ConsoleApplication2{    class Program    {        static void Main()        {            int[] m = new int[100];            for (int i = 0; i < m.Length; i++)                m[i] = (short)i;        }    }}


按理说100000个整形应当占400K,409+400=809,不应该是853呀!有谁知道是什么原因么?
C#的内存分配管理究竟有什么细节是我们不清楚的,而出现了这样的情况?

btw:现在http://acm.timus.ru/几乎快成了大家搞性能测试的地方了

[解决办法]
帮楼主顶。
[解决办法]
Mark
[解决办法]
友情一顶
再顶
顶不过三。
[解决办法]
期待大牛的出现.
[解决办法]
友情帮顶
[解决办法]
1220用C#实在是太困难了,我最接近的一次是850多K,每次都是在Text#1的时候MLE
[解决办法]
加精之,希望有人能解楼主之惑
[解决办法]
探讨
呵呵,我也是从1220开始的,跑到了test10 MLE了,空军同志跑到了test11,很不容易了。
我第一次跑到test10的时候,以为离目标不远了,可后来用c++解了一遍才知道,其实还远着呢。
test10\test12\test16 都是难点,我用c++写了一个529K AC的(换成纯C的应该可以低于500K),
但换算成C#,恐怕要850K以上了,距离目标还是有很远的距离的。

引用:
1220用C#实在是太困难了,我最接近的一次是850多K,每次都…

[解决办法]
顶!
[解决办法]
顶起楼上的...
[解决办法]
留名关注,抱歉楼主,改日我会学C#
[解决办法]
顶,顶。
------解决方案--------------------


UP~
[解决办法]
有,有,有点意思。。。。
[解决办法]
好,厉害啊
[解决办法]
超级牛人
[解决办法]
不知道楼主的内存怎么算出来的?或者从哪里看的?

在taskmgr里面的内存是:

working set=50,864K(50M左右)
Memory(Private working set) = 4,920K(5M左右)
Commit size = 6,688K(7M左右)

如果看gc的heap
GC Heap Size 0x7244(29252),一共29K

你说的的内存究竟是哪个?
[解决办法]
用楼主的第一个demo得到上面的结果的
[解决办法]
牛人
[解决办法]
好久以前见过的东西了,现在竟然看不懂了,真是惭愧。
[解决办法]
学习,虽然看不懂,但是也要留名
[解决办法]
操作系统对于内存分配是按页分配,也就是可以这样看待:对于大于一页的内存,需要使用时才能给与内存。
[解决办法]
学习了
[解决办法]
需要学习的地方真是太多了~~
[解决办法]
还有C#中的数组不是在栈上分配的内存的。。。
[解决办法]
不懂,关注
[解决办法]
顶下
[解决办法]
历害
[解决办法]
人不少啊
[解决办法]
顶!
[解决办法]
现在内存便宜了

[解决办法]
很好 爱恨很好啊啊
[解决办法]

探讨
操作系统对于内存分配是按页分配,也就是可以这样看待:对于大于一页的内存,需要使用时才能给与内存。

[解决办法]
学习下.........
[解决办法]
Mark!
[解决办法]
2551361 19:41:32 9 Apr 2009 xenium9 1000 C# Accepted 0.125 14 481 KB
C# code
class A{   static void Main()  {    int[] m = new int[3500000];    for (int i = 0; i < m.Length; i++)       // <--- 使用 m 的全部    {      m[i] = i;    }    string[] s = System.Console.ReadLine().Split();    System.Console.WriteLine(int.Parse(s[0]) + int.Parse(s[1]));  }}
[解决办法]
mark..
[解决办法]
楼主你是在探讨内存分配的问题吗?学习
[解决办法]
通过c#测试工具测试下
[解决办法]
好帖子,学习了要顶,
看高手门解答。
------解决方案--------------------


不错。。。。

[解决办法]

[解决办法]


友情一顶!!
[解决办法]
mark,关注
[解决办法]
高层次编程
[解决办法]
Mark
[解决办法]
感觉挺好玩的,帮顶一下
[解决办法]
哎 好难
[解决办法]
真的很好
[解决办法]
要想清楚什么原因.. 自己写出一门语言来.
[解决办法]
ding
[解决办法]
顶下
[解决办法]
只能顶一个,关注一下!
[解决办法]
回帖是一种美德
[解决办法]
留名!
[解决办法]
真的很难的学习啊
[解决办法]
学习了

一般不用到这样对内存要求太高的……
以前都是汇编或者C写,现在是有界面了才用C#的……
[解决办法]
学习!
[解决办法]
高手啊
[解决办法]
很不错,可以学习学习
[解决办法]
留待测试!
[解决办法]
留名。。
x大根到此一游

[解决办法]
mark and up and study
[解决办法]

探讨
期待大牛的出现.

[解决办法]
看来楼主在这方面研究的比较深入呀,我就只知道一点c的内容方面的知识,哎,受教了,看来还得多学呀!
[解决办法]
标记下,学习学习!
[解决办法]
网站内存的统计方法你不知道,那无缘无故多出来的40K,你如何知道是好事还是坏事?
当我的程序是这样时:

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
int[] m = new int[100];
Console.ReadLine();
}
}
}

stack上的内存占用是:
0:000> !dso
OS Thread Id: 0xb30 (0)
ESP/REG Object Name
0023f158 01c034d0 Microsoft.Win32.SafeHandles.SafeFileHandle
0023f168 01c034d0 Microsoft.Win32.SafeHandles.SafeFileHandle
0023f19c 01c04c04 System.Byte[]
0023f1a0 01c034e4 System.IO.__ConsoleStream
0023f1c0 01c0498c System.IO.StreamReader
0023f1c4 01c0498c System.IO.StreamReader
0023f1dc 01c0498c System.IO.StreamReader
0023f1e0 01c04f20 System.IO.TextReader+SyncTextReader


0023f200 01c04f20 System.IO.TextReader+SyncTextReader
0023f224 01c0330c System.Int32[]
0023f228 01c0330c System.Int32[]
0023f22c 01c032fc System.Object[] (System.String[])
0023f2e4 01c032fc System.Object[] (System.String[])
0023f498 01c032fc System.Object[] (System.String[])
0023f4c0 01c032fc System.Object[] (System.String[])

而那个数组int[] m = new int[100]中,实际占用的空间是:
0:000> !da 01c0330c 
Name: System.Int32[]
MethodTable: 69f3a9fc
EEClass: 69cfb4d4
Size: 412(0x19c) bytes
Array: Rank 1, Number of elements 100, Type Int32
Element Methodtable: 69f3aaac

412个字节而已。

但是占用了412,是否意味着仅仅分配了412个字节呢?
你建立了一个1字节的文本文件,是否意味着文件在磁盘只占用1个字节呢?扇区另外的空间也可以给别的文件使用呢?这是同样的道理,楼主你仔细想想。

再看heap的,看看内存里面都是啥:
0:000> !dumpheap -stat
total 315 objects
Statistics:
MT Count TotalSize Class Name
6a56be7c 1 16 System.IO.TextReader+SyncTextReader
69f3ba58 1 16 System.Text.DecoderReplacementFallback
69f3ba08 1 16 System.Text.EncoderReplacementFallback
69f3d78c 1 20 Microsoft.Win32.SafeHandles.SafeFileHandle
69f3adc4 1 20 System.Security.PermissionToken
69f37a80 1 20 Microsoft.Win32.SafeHandles.SafeFileMappingHandle
69f37a28 1 20 Microsoft.Win32.SafeHandles.SafeViewOfFileHandle
69f3799c 1 20 System.Text.InternalEncoderBestFitFallback
69f3a740 2 24 System.Security.Permissions.SecurityPermission
69f3a484 1 24 System.OperatingSystem
69f379e8 1 24 System.Text.InternalDecoderBestFitFallback
6a569214 1 28 System.Text.DBCSCodePageEncoding+DBCSDecoder
69f38f2c 1 28 System.SharedStatics
69f383bc 1 28 System.IO.Stream+NullStream
69f37c10 1 28 Microsoft.Win32.Win32Native+InputRecord
69f41c70 1 32 System.Text.UnicodeEncoding+Decoder
69f3ae70 1 32 System.Security.PermissionTokenFactory
69f3a240 1 32 Microsoft.Win32.Win32Native+OSVERSIONINFO
69f153a8 1 32 System.Text.UnicodeEncoding
69f3ae24 1 36 System.Security.Util.TokenBasedSet
69f3ac8c 1 36 System.Security.Permissions.FileIOPermission
69f3a03c 1 36 System.Int64[]
69f37c64 1 36 System.IO.__ConsoleStream
69f3a348 1 40 Microsoft.Win32.Win32Native+OSVERSIONINFOEX
69f3a700 1 44 System.Security.FrameSecurityDescriptor
69f3934c 1 44 System.AppDomainSetup
69f3d9f8 4 48 System.UInt16
69f3a7e8 3 48 System.Security.Permissions.FileIOAccess
69f3a408 2 48 System.Version
69f39dac 2 48 System.Reflection.Assembly
69f3ab88 2 56 System.Collections.ArrayList+ArrayListEnumeratorSimple
69f38e34 1 56 System.Threading.Thread
69f2430c 1 60 System.IO.StreamReader+NullStreamReader
69f24220 1 60 System.IO.StreamReader
69f3b688 1 68 System.Globalization.CultureTable
69f3a830 3 72 System.Security.Util.StringExpressionSet
69f3a524 2 72 System.Security.PermissionSet
69f38ba4 1 72 System.ExecutionEngineException
69f38b14 1 72 System.StackOverflowException
69f38a84 1 72 System.OutOfMemoryException
6a5690e8 1 76 System.Text.DBCSCodePageEncoding
69f3847c 8 96 System.Object
69f3b71c 5 100 System.Globalization.CultureTableItem
69f39040 1 100 System.AppDomain
0044e678 7 100 Free
69f3aaac 9 108 System.Int32


69f3899c 6 120 System.Text.StringBuilder
69f3b7c4 1 128 System.Globalization.NumberFormatInfo
69f3b638 3 144 System.Globalization.CultureTableRecord
69f3a890 6 144 System.Collections.ArrayList
69f38c34 2 144 System.Threading.ThreadAbortException
69f399e0 8 160 System.RuntimeType
69f39f58 3 192 System.IO.UnmanagedMemoryStream
69f3b45c 3 204 System.Globalization.CultureInfo
69f3aeb4 7 392 System.Collections.Hashtable
69f3b2d0 4 436 System.Byte[]
69f3afb0 7 1008 System.Collections.Hashtable+bucket[]
69f39490 19 1248 System.Char[]
69f3a9fc 10 2388 System.Int32[]
69f38860 127 6696 System.String
69f14e8c 26 9452 System.Object[]
Total 315 objects

并不是说,你new了一个数组,内存里面只有你自己的东西的。也并不是说,你跑了一个循环,内存就是你想象的方式来做的。
唯一的办法,你要把内存dump出来,这样才能研究清楚。


[解决办法]
大家探讨探讨,有助于理解内存分配问题。
[解决办法]
学习
[解决办法]
UP
[解决办法]
.NET内部的事情,可以用windbg看出一些。

我以前写过的一些post,你可以参考一下:

http://www.cnblogs.com/juqiang/category/118306.html


[解决办法]
需要学习的地方真是太多了~~
[解决办法]
不错

探讨
需要学习的地方真是太多了~~

[解决办法]
4K为一页 阿
[解决办法]
up
顶!
[解决办法]
我看不懂,但也要坚持学。
[解决办法]
有意思.
[解决办法]
顶一下
[解决办法]
标记一下,留着有用…
[解决办法]
4K 为一页外还有个问题就是 CLR工作 对于申请内存的操作,
需要查看CLR是否已经有申请的内存可供使用,如果有则分配它,
也就是说在CLR在开始分配,会分配多余你需要的内存是必要的,
下次分配时就不用向OS申请了,这只是优化措施。要不然MS会鼓吹,
C#的在堆上申请空间几乎和栈一样快,可见还是没有栈快,如果你想在在栈分配空间C#还是可以的
可以使用int* p = stackalloc int[100];
[解决办法]
1000 0.062 381 KB 
1000 0.078 389 KB 
1000 0.078 389 KB 
1000 0.109 385 KB 
1000 0.093 389 KB 
1000 0.109 385 KB 
1000 0.062 389 KB 
1000 0.093 385 KB 
1000 0.078 397 KB 
1000 0.093 389 KB 
 同一个函数 结果
C# code
 class Program {   static void Main(string[] args)   {   } }
[解决办法]
学习中~~~~ 支持下
[解决办法]
up ..

热点排行