Ray*_*Ray 16 .net c# memory-management list
我的问题可能听起来有点模糊.但我想知道的是List<>缓冲区的维护位置.
我有一个列表List<MyClass>,我从无限循环添加项目.但Windows服务(我在其中创建List)的RAM消耗从未超过17 MB.事实上,即使我继续向列表中添加项目,它也会徘徊在15-16MB之间.我试图做一些负载测试我的服务,并遇到了这个问题.
谁能告诉我它是否将数据转储到机器上的某个临时位置,并从那里选择它,因为我没有看到RAM消耗的增加.
我无限调用的方法是AddMessageToList().
class MainClass
{
List<MessageDetails> messageList = new List<MessageDetails>();
private void AddMessageToList()
{
SendMessage(ApplicationName,Address, Message);
MessageDetails obj= new MessageDetails();
obj.ApplicationName= ApplicationName;
obj.Address= Address;
obj.Message= Message;
lock(messageList)
{
messageList.Add(obj);
}
}
}
class MessageDetails
{
public string Message
{
get;
set;
}
public string ApplicationName
{
get;
set;
}
public string Address
{
get;
set;
}
}
Run Code Online (Sandbox Code Playgroud)
Bra*_*NET 28
你的问题的答案是:"在记忆中".
这可能意味着RAM,它也可能意味着硬盘(虚拟内存).操作系统内存管理器决定何时将内存分页到虚拟内存,这主要与访问内存的频率有关(尽管我并不假装知道微软的特定算法).
你也问过为什么你的记忆用法不会上升.首先,MegaByte是一个巨大的内存.除非你的课程很大,否则你需要很多才能出现MB.最终你的内存使用率会上升.
通常,C#对象是从Heap创建的,它位于内存中.如果你想在磁盘上存储东西,有办法解决它,但标准List<T>将存在于内存中.
当你创建一个对象时,它将占用内存中的一定数量的字节加上用于引用它的指针的大小.将它添加到列表只会添加指向您已创建的对象的指针,因此如果您要将同一实例的大量副本添加到列表中,它将不会像您期望的那样快速增长.
如果你真的想测试大数据结构对你内存的影响,你将不得不提高数字.几千个普通对象不会占用太多内存,但可能会有几百万个.
您可能也对该GC.GetTotalMemory()方法及其朋友感兴趣.
请注意,Windows(和.NET)上几乎所有内存都是虚拟内存 - 它的"真实,物理"位置是任意的,Windows内存管理处理它.但是,无论它当前是在HDD上使用物理RAM还是页面文件,它都将显示为已提交的专用内存.
所以这取决于你是如何实际创建项目并将它们添加到List<T>.有多少个物体?您是一遍又一遍地添加相同的对象,还是每次都创建一个新对象?您使用的是相同的List实例,还是在创建其他实例?您是否保留对创建的对象(和列表实例)的引用,还是将它们丢弃?你真的对对象/列表做了什么吗?如果没有,优化器可能已经完全删除了代码(虽然它非常保守,所以我不会指望将项添加到列表中 - 这是一个非常复杂的情况,可能有副作用).
在最低内存理想情况下,你可以使用每个列表项大约四个字节,这并不多 - 你需要262 144个项目来消耗一个MiB内存!
向我们展示您的代码,整个循环及其周围环境.然后我们就可以告诉你,你有什么实际做的事情.
编辑:这是在WCF服务?你之前应该这样说过.你在哪里存储的MainClass类?如果它在WCF服务类中,它可能不会比单个请求持续更长时间.即使你修复它,并将它存储在一些更持久的东西中,比如静态类,你会遇到收集所有内容,如何重新启动服务等的复杂性.如果你需要安全地保存数据如果时间长于单个请求,则将其存储在进程内存中是不够的.如果您不关心数据偶尔会丢失,您可以使List实例静态(不会共享,也不会持久化).否则,请使用数据库.