Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在.NET中绕过2 GB的收集限制_C#_.net_List_Exception_Collections - Fatal编程技术网

C# 在.NET中绕过2 GB的收集限制

C# 在.NET中绕过2 GB的收集限制,c#,.net,list,exception,collections,C#,.net,List,Exception,Collections,,我想我可以通过使用以下模式创建一个BigList数据类型来绕过2GB集合大小限制(顺便说一句,如果您想尝试一下,这个限制似乎是默认强加在x86应用程序上的): 使用Microsoft.Win32; 使用制度; 使用System.Collections.Generic; 使用System.Linq; 使用系统文本; 使用系统线程; 使用System.Threading.Tasks; 名称空间注册表 { 班级计划 { 结构注册表路径 { 公共注册视图; 公共字符串路径; 公共bool-IsKey;

,我想我可以通过使用以下模式创建一个BigList数据类型来绕过2GB集合大小限制(顺便说一句,如果您想尝试一下,这个限制似乎是默认强加在x86应用程序上的):

使用Microsoft.Win32;
使用制度;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统线程;
使用System.Threading.Tasks;
名称空间注册表
{
班级计划
{
结构注册表路径
{
公共注册视图;
公共字符串路径;
公共bool-IsKey;
公共注册处ValueKind ValueKind;
公共字符串ValueName;
公共客体价值;
公共值;
}
公共类大列表
{
object listLock=新对象();
列表项=新列表();
int PageSize=1000000;//将其调整为在达到.NET的2 GB大小限制之前,可以增加每个列表的最大大小。
公共ulong计数=0;
int listCount=0;
公共大名单()
{
添加(新列表());
}
公共作废新增(T项)
{
锁(列表锁)
{
if(Items[listCount].Count==PageSize)
{
添加(新列表());
listCount++;
}
项目[listCount]。添加(项目);
计数++;
}
}
}
静态void Main(字符串[]参数)
{
BigList snapshotOne=新的BigList();
步行登记并填写快照(快照一);
BigList snapshotTwo=新的BigList();
步行登记并填写快照(快照二);
}
私有静态无效漫游注册表和人口快照(大列表快照)
{
列表句柄=新列表();
foreach(Enum.GetValues中的RegistryHive配置单元(typeof(RegistryHive)))
{
foreach(Enum.GetValues(typeof(RegistryView)).Cast().ToList()中的RegistryView视图。其中(x=>x!=RegistryView.Default))
{
ManualResetEvent ManualResetEvent=新的ManualResetEvent(错误);
句柄。添加(手动重置事件);
新线程(()=>
{
WalkKey(快照、视图、注册表项、OpenBaseKey(配置单元、视图));
manualResetEvent.Set();
}).Start();
}
}
ManualResetEvent.WaitAll(handles.ToArray());
}
私有静态void WalkKey(BigList快照、RegistryView视图、RegistryKey)
{
RegistryPath path=new RegistryPath{View=View,path=key.Name,HashValue=(View.GetHashCode()^key.Name.GetHashCode()).GetHashCode()};
snapshot.Add(路径);
字符串[]valueNames=null;
尝试
{
valueNames=key.GetValueNames();
}
捕获{}
if(valueNames!=null)
{
foreach(valueNames中的字符串valueName)
{
RegistryValueKind valueKind=RegistryValueKind.Unknown;
尝试
{
valueKind=key.GetValueKind(valueName);
}
捕获{}
对象值=key.GetValue(valueName);
RegistryPath pathForValue=new RegistryPath{View=View,Path=key.Name,ValueKind=ValueKind,ValueName=ValueName,Value=Value,HashValue=(View.GetHashCode()^key.Name.GetHashCode()^ValueKind.GetHashCode()).GetHashCode()};
snapshot.Add(pathForValue);
}
}
string[]subKeyNames=null;
尝试
{
subKeyNames=key.GetSubKeyNames();
}
捕获{}
if(子关键字名称!=null)
{
foreach(subKeyName中的字符串subKeyName)
{
尝试
{
WalkKey(快照、视图、key.OpenSubKey(subKeyName));
}
捕获{}
}
}
}
}
}

但是,CLR仍然会触发
System.OutOfMemory
异常。它不会在任何地方抛出,但我看到程序执行完全停止在2GB左右的RAM上,当我在Visual Studio中冻结代码时,它表明每当我试图查看应用程序任何线程中的变量状态时,都会抛出内存不足异常。在第一次调用
WalktheRegistr并填充快照(snapshotOne)时,不会发生这种情况,但当第二次调用
WalktheRegistr并填充快照(快照二)时继续,它最终会在我的集合中总RAM使用量约为2GB的情况下停止程序执行。整个代码都已发布,因此如果您有一个强大的注册表,您可能会看到它是在x86控制台应用程序上生成的。是否有我在这里没有掌握的东西,或者这个模式不是绕过2 GB集合大小限制的有效方法,而堆栈上的另一个问题似乎达到了这个限制?

我将对我的评论进行扩展。如果您正在编写一个32位应用程序,那么在处理大量数据时,您会遇到一些严重的内存限制

需要记住的最重要的一点是,32位应用程序的内存限制为绝对最大2^32字节(4 GB)。实际上,它通常是2GB,如果您有那么多内存并且应用程序具有大的地址感知能力,则可能是3MB

还有.NET强加的2GB限制,这限制了
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace RegistryHawk
{
    class Program
    {

        struct RegistryPath
        {
            public RegistryView View;
            public string Path;
            public bool IsKey;
            public RegistryValueKind ValueKind;
            public string ValueName;
            public object Value;
            public int HashValue;
        }

        public class BigList<T>
        {
            object listLock = new object();
            List<List<T>> Items = new List<List<T>>();
            int PageSize = 1000000; // Tweak this to be the maximum size you can grow each individual list before reaching the 2 GB size limit of .NET.
            public ulong Count = 0;
            int listCount = 0;

            public BigList()
            {
                Items.Add(new List<T>());
            }

            public void Add(T item)
            {
                lock (listLock)
                {
                    if (Items[listCount].Count == PageSize)
                    {
                        Items.Add(new List<T>());
                        listCount++;
                    }
                    Items[listCount].Add(item);
                    Count++;
                }
            }
        }

        static void Main(string[] args)
        {
            BigList<RegistryPath> snapshotOne = new BigList<RegistryPath>();
            WalkTheRegistryAndPopulateTheSnapshot(snapshotOne);
            BigList<RegistryPath> snapshotTwo = new BigList<RegistryPath>();
            WalkTheRegistryAndPopulateTheSnapshot(snapshotTwo);
        }

        private static void WalkTheRegistryAndPopulateTheSnapshot(BigList<RegistryPath> snapshot)
        {
            List<ManualResetEvent> handles = new List<ManualResetEvent>();
            foreach (RegistryHive hive in Enum.GetValues(typeof(RegistryHive)))
            {
                foreach (RegistryView view in Enum.GetValues(typeof(RegistryView)).Cast<RegistryView>().ToList().Where(x => x != RegistryView.Default))
                {
                    ManualResetEvent manualResetEvent = new ManualResetEvent(false);
                    handles.Add(manualResetEvent);
                    new Thread(() =>
                    {
                        WalkKey(snapshot, view, RegistryKey.OpenBaseKey(hive, view));
                        manualResetEvent.Set();
                    }).Start();
                }
            }
            ManualResetEvent.WaitAll(handles.ToArray());
        }

        private static void WalkKey(BigList<RegistryPath> snapshot, RegistryView view, RegistryKey key)
        {
            RegistryPath path = new RegistryPath { View = view, Path = key.Name, HashValue = (view.GetHashCode() ^ key.Name.GetHashCode()).GetHashCode() };
            snapshot.Add(path);
            string[] valueNames = null;
            try
            {
                valueNames = key.GetValueNames();
            }
            catch { }
            if (valueNames != null)
            {
                foreach (string valueName in valueNames)
                {
                    RegistryValueKind valueKind = RegistryValueKind.Unknown;
                    try
                    {
                        valueKind = key.GetValueKind(valueName);
                    }
                    catch { }
                    object value = key.GetValue(valueName);
                    RegistryPath pathForValue = new RegistryPath { View = view, Path = key.Name, ValueKind = valueKind, ValueName = valueName, Value = value, HashValue = (view.GetHashCode() ^ key.Name.GetHashCode() ^ valueKind.GetHashCode() ^ valueName.GetHashCode()).GetHashCode() };
                    snapshot.Add(pathForValue);
                }
            }
            string[] subKeyNames = null;
            try
            {
                subKeyNames = key.GetSubKeyNames();
            }
            catch { }
            if (subKeyNames != null)
            {
                foreach (string subKeyName in subKeyNames)
                {
                    try
                    {
                        WalkKey(snapshot, view, key.OpenSubKey(subKeyName));
                    }
                    catch { }
                }
            }
        }
    }
}