regex命令循环中出现内存不足错误

本文关键字:内存不足 错误 命令 循环 regex | 更新日期: 2023-09-27 18:01:00

运行regex后,我将字符串设置为null并强制垃圾回收,但出现内存不足错误。

手动调用垃圾回收器没有任何作用。我对空字符串使用null

int i = 0;
while (i < 40 )
{
    string strFile42 = File.ReadAllText(@"C:'Users'diego'Desktop'finalregex.txt"); 
    string Value3 = @"'n(.*?)&" ;
    string Value4 =string.Format("'n$1#{0}#", i);
    //Force garbage collection.
    GC.Collect();
    strFile42 = Regex.Replace(strFile42, Value3, Value4);
    //Force garbage collection.
    GC.Collect();
    Value4 = null;
    Value3 = null;
    GC.Collect();
    GC.WaitForPendingFinalizers();
    File.WriteAllText(@"C:'Users'diego'Desktop'finalregex.txt", strFile42);
    strFile42 =null;
    GC.Collect();
    GC.WaitForPendingFinalizers();
    i = i + 1;
}

==============================================

这是我的解决方案

      string strFile42 =  File.ReadAllText(@"C:'Users'diego'Desktop'finalregex.txt");

 '' regex code for replace (PUT REGEX CODE HERE )

    File.WriteAllText(@"C:'Users'diego'Desktop'finalregex.txt", strFile42);

    strFile42 = null ;
  int oldCacheSize = Regex.CacheSize;
Regex.CacheSize         = 0;
  GC.Collect();
    Regex.CacheSize = oldCacheSize; 
  GC.Collect();
 GC.WaitForPendingFinalizers();

regex命令循环中出现内存不足错误

当您使用时,您会为字符串分配巨大的大小:string strFile42=File.ReadAllText(文件名(;一次对这么大的大小执行Regex.Replace表示内存开销。

字符串是在大对象堆上分配的,GC不会将其与其他小对象一起收集。当您调用GC.Collect((来撤销垃圾收集器时,GCCANNOT会保证立即收集字符串。

因此,最好将BufferedStream与StreamReader一起使用,一次处理一行,而不需要任何内存开销。

我测量了执行过程中用于监控内存分配的内存。

下面的类可以处理巨大的文件而没有任何问题

  public void FileProcess()
    {
        Process proc = Process.GetCurrentProcess();
        int i = 0;
        while (i < 40)
        {
            Console.WriteLine(" i: {0} - Private memory: {1} KB- Memory Used: {2} KB", i,
                proc.PrivateMemorySize64/1024.0, GC.GetTotalMemory(true)/1024.0);    
            var path = "test0.txt";
            var path2 = "test2.txt";
            using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read))
            using (BufferedStream bs = new BufferedStream(fs))
            using (StreamReader sr = new StreamReader(bs))
            using (StreamWriter outputFile = new StreamWriter(path2))
            {
                string line;
                while ((line = sr.ReadLine()) != null)
                {
                    var text = ProcessLine(line, i);
                    outputFile.WriteLine(text);
                }
            }
            i++;
            // Collect all generations of memory.
            // GC.Collect(); //you need not
        } //while
    }
    private string ProcessLine(string text, int i)
    {
        string Value3 = @"(.*?)&";
        string Value4 = string.Format("$1#{0}#", i);
        var strFile42 = Regex.Replace(text, Value3, Value4);
        return strFile42;
    }
}

基准性能测试:

我生成了一个大小为72MB的字符串文件,并使用该类处理该文件40次,根本没有任何开销。正如您所看到的,应用程序使用的内存大约为252K,并且在没有GC收集的情况下一直保持不变。

结果

     i: 0 - Private memory: 18212 KB- Memory Used: 251.8828125 KB
     i: 1 - Private memory: 18212 KB- Memory Used: 274.5390625 KB
     i: 2 - Private memory: 18212 KB- Memory Used: 274.5390625 KB
     i: 3 - Private memory: 18212 KB- Memory Used: 274.5390625 KB
     i: 4 - Private memory: 18212 KB- Memory Used: 274.5390625 KB
     i: 5 - Private memory: 18212 KB- Memory Used: 274.5390625 KB
     i: 6 - Private memory: 18212 KB- Memory Used: 274.5390625 KB
     i: 7 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 8 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 9 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 10 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 11 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 12 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 13 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 14 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 15 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 16 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 17 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 18 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 19 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 20 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 21 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 22 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 23 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 24 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 25 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 26 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 27 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 28 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 29 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 30 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 31 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 32 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 33 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 34 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 35 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 36 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 37 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 38 - Private memory: 18212 KB- Memory Used: 274.48828125 KB
     i: 39 - Private memory: 18212 KB- Memory Used: 274.48828125 KB

我想知道Regex的cashSize是否不是问题所在。

在MSDN信息中,有一个关于Regex 的页面

报价:

Regex类维护静态方法调用中使用的已编译正则表达式的内部缓存。如果在设置操作中指定的值小于当前缓存大小,则会丢弃缓存项,直到缓存大小等于指定值。默认情况下,缓存包含15个已编译的静态正则表达式。您的应用程序通常不必修改缓存的大小。仅当您希望关闭缓存或缓存异常大时,才使用CacheSize属性。

这里有一个关于Regex 的CashSize的问题

我在这里发布我的答案

我用这个代码清理内存泄漏

        string strFile42 =  File.ReadAllText(@"C:'Users'diego'Desktop'finalregex.txt");

  '' regex code for replace (PUT REGEX CODE HERE )

     File.WriteAllText(@"C:'Users'diego'Desktop'finalregex.txt", strFile42);

      strFile42 = null ;
   int oldCacheSize = Regex.CacheSize;
  Regex.CacheSize         = 0;
   GC.Collect();
        Regex.CacheSize = oldCacheSize; 
    GC.Collect();
GC.WaitForPendingFinalizers();