我需要处理大量的 float 列表,但我在 x86 系统上遇到了内存限制。我不知道最终长度,所以我需要使用可扩展的类型。在 x64 系统上,我可以使用 <gcAllowVeryLargeObjects> .
我当前的数据类型:
List<RawData> param1 = new List<RawData>();
List<RawData> param2 = new List<RawData>();
List<RawData> param3 = new List<RawData>();
public class RawData
{
public string name;
public List<float> data;
}
paramN 列表的长度很低(目前为 50 或更低),但数据可以超过 10m。当长度为 50 时,我在 1m 数据点上方达到内存限制 ( OutOfMemoryException ),而当长度为 25 时,我在 2m 数据点上方达到内存限制。 (如果我的计算正确,那正好是 200MB,加上名称的大小,再加上开销)。我可以使用什么来增加此限制?
编辑:我尝试使用 List<List<float>>最大内部列表大小为 1 < 17="">
Edit2:我尝试将 List> 中的 block 大小减小到 8192,我在 ~2.3m 元素处得到了 OOM,任务管理器为进程读取了 ~1.4GB。看起来我需要减少数据源和存储之间的内存使用,或者更频繁地触发 GC - 我能够在具有 4GB RAM 的 pc 上的 x64 进程中收集 10m 数据点,IIRC 该进程从未超过 3GB
Edit3:我将我的代码压缩为仅处理数据的部分。 http://pastebin.com/maYckk84
Edit4:我查看了 DotMemory,发现我的数据结构确实占用了大约 1GB 的空间和我测试的设置(50ch * 3 params * 2m events = 300,000,000 float elements) .我想我需要在 x86 上限制它,或者弄清楚如何在获取数据时以这种格式写入磁盘
最佳答案
首先,在 x86 系统上内存限制是 2GB,而不是 200MB。我相信
你的问题比那更棘手。您有严重的 LOH(大对象堆)碎片。
CLR 对小型和大型对象使用不同的堆。如果对象的大小大于 85,000 字节,则对象很大。 LOH 是一个非常暴躁的东西,它不急于将未使用的内存归还给操作系统,并且在碎片整理方面很差。
.Net List是ArrayList数据结构的实现,将元素存储在数组中,数组大小固定;当数组被填满时,将创建一个双倍大小的新数组。阵列随着数据量的不断增长是 LOH 的“饥饿”场景。
因此,您必须使用量身定制的数据结构来满足您的需求。例如。 block 列表,每个 block 都足够小,不会进入 LOH。这是小原型(prototype):
public class ChunkedList
{
private readonly List<float[]> _chunks = new List<float[]>();
private const int ChunkSize = 8000;
private int _count = 0;
public void Add(float item)
{
int chunk = _count / ChunkSize;
int ind = _count % ChunkSize;
if (ind == 0)
{
_chunks.Add(new float[ChunkSize]);
}
_chunks[chunk][ind] = item;
_count ++;
}
public float this[int index]
{
get
{
if(index <0 || index >= _count) throw new IndexOutOfRangeException();
int chunk = index / ChunkSize;
int ind = index % ChunkSize;
return _chunks[chunk][ind];
}
set
{
if(index <0 || index >= _count) throw new IndexOutOfRangeException();
int chunk = index / ChunkSize;
int ind = index % ChunkSize;
_chunks[chunk][ind] = value;
}
}
//other code you require
}
当 ChunkSize = 8000 时,每个 block 将只占用 32,000 字节,因此它不会进入 LOH。 _chunks 只有在集合中有大约 16,000 个 block 时才会进入 LOH,这超过了集合中的 1.28 亿个元素(约 500 MB)。
UPD 我已经对上面的示例进行了一些压力测试。操作系统是x64,解决方案平台是x86。 ChunkSize 为 20000。
首先:
var list = new ChunkedList();
for (int i = 0; ; i++)
{
list.Add(0.1f);
}
在大约 324,000,000 个元素处引发 OutOfMemoryException
第二个:
public class RawData
{
public string Name;
public ChunkedList Data = new ChunkedList();
}
var list = new List<RawData>();
for (int i = 0;; i++)
{
var raw = new RawData { Name = "Test" + i };
for (int j = 0; j < 20 * 1000 * 1000; j++)
{
raw.Data.Add(0.1f);
}
list.Add(raw);
}
在 i=17,j~12,000,000 时引发 OutOfMemoryException。成功创建17个RawData实例,每个实例2000万个数据点,总共约3.52亿个数据点。
关于c# - 在 x86 上处理非常大的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31486475/
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
是否有类似“RVMuse1”或“RVMuselist[0]”之类的内容而不是键入整个版本号。在任何时候,我们都会看到一个可能包含5个或更多ruby的列表,我们可以轻松地键入一个数字而不是X.X.X。这也有助于rvmgemset。 最佳答案 这在RVM2.0中是可能的=>https://docs.google.com/document/d/1xW9GeEpLOWPcddDg_hOPvK4oeLxJmU3Q5FiCNT7nTAc/edit?usp=sharing-知道链接的任何人都可以发表评论
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
Rails相对较新。我正在尝试调用一个API,它应该向我返回一个唯一的URL。我的应用程序中捆绑了HTTParty。我已经创建了一个UniqueNumberController,并且我已经阅读了几个HTTParty指南,直到我想要什么,但也许我只是有点迷路,真的不知道该怎么做。基本上,我需要做的就是调用API,获取它返回的URL,然后将该URL插入到用户的数据库中。谁能给我指出正确的方向或与我分享一些代码? 最佳答案 假设API为JSON格式并返回如下数据:{"url":"http://example.com/unique-url"
我对图像处理完全陌生。我对JPEG内部是什么以及它是如何工作一无所知。我想知道,是否可以在某处找到执行以下简单操作的ruby代码:打开jpeg文件。遍历每个像素并将其颜色设置为fx绿色。将结果写入另一个文件。我对如何使用ruby-vips库实现这一点特别感兴趣https://github.com/ender672/ruby-vips我的目标-学习如何使用ruby-vips执行基本的图像处理操作(Gamma校正、亮度、色调……)任何指向比“helloworld”更复杂的工作示例的链接——比如ruby-vips的github页面上的链接,我们将不胜感激!如果有ruby-
我正在使用Rails3.2.3和Ruby1.9.3p0。我发现我经常需要确定某个字符串是否出现在选项列表中。看来我可以使用Ruby数组.includemethod:或正则表达式equals-tildematchshorthand用竖线分隔选项:就性能而言,一个比另一个好吗?还有更好的方法吗? 最佳答案 总结:Array#include?包含String元素,在接受和拒绝输入时均胜出,对于您的示例只有三个可接受的值。对于要检查的更大的集合,看起来Set#include?和String元素可能会获胜。如何测试我们应该根据经验对此进行测试
我有一个super简单的脚本,它几乎包含了FayeWebSocketGitHub页面上用于处理关闭连接的内容:ws=Faye::WebSocket::Client.new(url,nil,:headers=>headers)ws.on:opendo|event|p[:open]#sendpingcommand#sendtestcommand#ws.send({command:'test'}.to_json)endws.on:messagedo|event|#hereistheentrypointfordatacomingfromtheserver.pJSON.parse(event.d
我正在尝试解析网页,但有时会收到404错误。这是我用来获取网页的代码:result=Net::HTTP::getURI.parse(URI.escape(url))如何测试result是否为404错误代码? 最佳答案 像这样重写你的代码:uri=URI.parse(url)result=Net::HTTP.start(uri.host,uri.port){|http|http.get(uri.path)}putsresult.codeputsresult.body这将打印状态码和正文。