C# 向列表中添加整数时引发System.OutOfMemoryException

C# 向列表中添加整数时引发System.OutOfMemoryException,c#,out-of-memory,C#,Out Of Memory,我是一个非常业余的C#开发者,正试图使用VisualStudio在macOS上开发这个控制台程序。我是在学校做的,但我是自学成才的,在这方面的工作还不到两周,所以我完全有可能错过了一些简单的解决办法 我制作了一个程序,读取一个充满素数的文本文件并将其转换成一个列表,然后开始生成素数,同时将它们添加到列表和文件中,并在每次发现新的素数时同时报告信息 以下是我的代码: String fileLocation = "Prime Number List.txt"; //sets the file loc

我是一个非常业余的C#开发者,正试图使用VisualStudio在macOS上开发这个控制台程序。我是在学校做的,但我是自学成才的,在这方面的工作还不到两周,所以我完全有可能错过了一些简单的解决办法

我制作了一个程序,读取一个充满素数的文本文件并将其转换成一个列表,然后开始生成素数,同时将它们添加到列表和文件中,并在每次发现新的素数时同时报告信息

以下是我的代码:

String fileLocation = "Prime Number List.txt"; //sets the file location to the root of where the program is stored

if (!File.Exists(fileLocation)) //tests if the file has already been created
{
    using (FileStream fs = File.Create(fileLocation))
    {
        Byte[] info = new UTF8Encoding(true).GetBytes("2"); //if not, it creates the file and creates the initial prime number of 2
        fs.Write(info, 0, info.Length);
    }
}


List<string> fileContents = File.ReadAllLines(fileLocation).ToList(); //imports the list of prime numbers from the file
List<int> listOfPrimeNumbers = fileContents.ConvertAll(s => Int32.Parse(s)); //converts the list into the integer variable type


int currentNumber = listOfPrimeNumbers[listOfPrimeNumbers.Count() - 1]; //sets the current number to the most recent prime number
bool isPrime; //initializing the primality test variable
int numbersGeneratedThisSession = 0; //initializing the variable for the amount of primes found in this session
var loopStart = DateTime.Now; //initializes the program start time, ignoring the time taken to load the file list

while (true)
{
    isPrime = true; //defaults the number to prime
    currentNumber++; //repeats the cycle for the next number
    double currentNumberRoot = Math.Sqrt(System.Convert.ToDouble(currentNumber));
    for (int i = 0; i < listOfPrimeNumbers.Count; i++) //cyles through all of the primes in the list. no reason to divide by composites, as any number divisible by a
                                                            //composite would be divisible by the prime factors of that composite anyway, thus if we were to divide by
                                                            //every number it would slow down the program
    {
        if (listOfPrimeNumbers[i] < Math.Sqrt(System.Convert.ToDouble(currentNumber))) //filters out any prime numbers greater than the square root of the current number, as any potential
                                                                                            //factor pair would have one of the values less than or equal to the square root
        {
            if (currentNumber % listOfPrimeNumbers[i] == 0) //checks for the even division of the current number by the current prime
            {
                isPrime = false; //if an even division is found, it reports that the number isn't false and breaks the loop
                break;
            }
        }

        else
            break; //if no even divisons are found, then it reaches this point with the primality test variable still true, and breaks the loop



    }
    if (isPrime) //this section of the code activates when the primality test variable is true
    {
        listOfPrimeNumbers.Add(currentNumber); //adds the new prime to the list
        File.AppendAllText(fileLocation, Environment.NewLine + currentNumber); //adds the new prime to the file on a new line
        numbersGeneratedThisSession++; //raises the counter for the prime numbers generated in this session
        var runtime = DateTime.Now - loopStart; //calculates the runtime of the program, excluding the time taken to load the file into the list
        int runtimeInSecs = (runtime.Milliseconds / 1000) + runtime.Seconds + (runtime.Minutes * 60) + (runtime.Hours * 360) + (runtime.Days * 86400); //converts the datetime var into an int of seconds
        int generationSpeed = runtimeInSecs == 0 ? 0 : numbersGeneratedThisSession / runtimeInSecs;
        Console.WriteLine("\nI've generated {0} prime numbers, {1} of those being in the current session." +
                          "\nI've been running for {2}, which means I've been generating numbers at a speed of {3} primes per second. " +
                          "\nThe largest prime I've generated so far is {4}, which is {5} digits long.", 
                          listOfPrimeNumbers.Count(), numbersGeneratedThisSession, runtime, generationSpeed, currentNumber, currentNumber.ToString().Length);
    }
}
stringfilelocation=“Prime Number List.txt”//将文件位置设置为存储程序的根目录
if(!File.Exists(fileLocation))//测试文件是否已创建
{
使用(FileStream fs=File.Create(fileLocation))
{
Byte[]info=new UTF8Encoding(true).GetBytes(“2”);//如果不是,则创建文件并创建初始素数2
fs.Write(信息,0,信息长度);
}
}
List fileContents=File.ReadAllLines(fileLocation.ToList()//从文件中导入素数列表
listofPrimeNumber=fileContents.ConvertAll(s=>Int32.Parse)//将列表转换为整数变量类型
int currentNumber=listOfPrimeNumbers[listOfPrimeNumbers.Count()-1]//将当前数字设置为最近的素数
bool-isPrime//初始化素性测试变量
int numbersgeneratedthis session=0//正在为此会话中找到的素数量初始化变量
var loopStart=DateTime.Now//初始化程序开始时间,忽略加载文件列表所用的时间
while(true)
{
isPrime=true;//默认值为素数
currentNumber++;//重复下一个数字的循环
double currentNumberRoot=Math.Sqrt(System.Convert.ToDouble(currentNumber));
for(int i=0;i
我一直在“ListofPrimeNumber.Add(currentNumber);”部分中遇到异常。我读过类似的问题,而解决其他人问题最常见的方法是将gcAllowVeryLargeObjects设置为true,以突破2GB限制。这对我来说是一个暂时的修复,但是随着时间的推移,列表会不断变大,当它达到我的计算机能力的极限而不是visual studio的上限时,会有一个点

我想知道是否有一些技术是更有经验的开发人员用来规避这个问题的,比如将数据拆分成多个列表,做一些与我不同的事情来简化代码,等等。我知道由于我的程序的性质,最终数据会变得太大是不可避免的,但我正试图尽可能地推迟,因为现在的文件不到半个gig,这是一个不合理的小内存量,足以使程序崩溃

我还想指出的是,在过去的一周里,我每天运行这个程序大约一个小时,当时我正在处理统计反馈(这意味着文件读取、写入和生成代码本身在这段时间内基本上没有被触及)。我在任何时候启动它都没有问题,它最后一次运行都很顺利(没有因为内存不足异常而崩溃)。I o
List<string> fileContents = File.ReadAllLines(fileLocation).ToList(); //imports the list of prime numbers from the file
List<int> listOfPrimeNumbers = fileContents.ConvertAll(s => Int32.Parse(s)); //converts the list into the integer variable type
//note that I used ReadLines, not ReadAllLines
 int lastNumber;
 if(!int.TryParse(File.ReadLines(fileLocation).ToList().Last(), out lastNumber))
 {
      //last value wasn't a valid integer.  Start over. 
      lastNumber = 1;
 }