Skip to main content
 首页 » 编程设计

c#之正则表达式命令循环中出现内存不足错误

2024年01月21日2898°冷暖

运行正则表达式后,我将字符串设置为 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(); 

请您参考如下方法:

当你使用时,你为字符串分配了巨大的空间: 字符串 strFile42 = File.ReadAllText(文件名); 一次对所有这么大的尺寸执行 Regex.Replace 表示内存开销。

字符串分配在大对象堆上,不会和其他小对象一起被GC回收。 当您调用 GC.Collect() 以撤销垃圾收集器时,GC 不能保证将立即收集该字符串。

因此,最好将 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; 
    } 
} 

基准性能测试:

我生成了大小为 72 MB 的字符串文件,并使用该类处理文件 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