Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.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# 数组c的内存泄漏#_C#_Arrays_Multithreading_Out Of Memory - Fatal编程技术网

C# 数组c的内存泄漏#

C# 数组c的内存泄漏#,c#,arrays,multithreading,out-of-memory,C#,Arrays,Multithreading,Out Of Memory,用户指定文件名和块大小。原始文件拆分为具有用户块大小的块(最后一个块除外)。对于每个块,计算哈希函数SHA256并写入控制台 这是一个有2个线程的程序:第一个线程读取原始文件并放入块的队列字节数组中;第二个线程从队列中删除块的字节数组并计算哈希 在第一次迭代之后,直到程序完成,内存才会被释放。 在下一次迭代中,内存正常分配和处理。 所以,在下一次读取part数组时,我得到了OutOfMemoryException 如何正确管理内存以避免内存泄漏 class Encryption { st

用户指定文件名和块大小。原始文件拆分为具有用户块大小的块(最后一个块除外)。对于每个块,计算哈希函数SHA256并写入控制台

这是一个有2个线程的程序:第一个线程读取原始文件并放入块的队列字节数组中;第二个线程从队列中删除块的字节数组并计算哈希

在第一次迭代之后,直到程序完成,内存才会被释放。
在下一次迭代中,内存正常分配和处理。
所以,在下一次读取part数组时,我得到了
OutOfMemoryException

如何正确管理内存以避免内存泄漏

class Encryption
{
    static FileInfo originalFile;
    static long partSize = 0; 
    static long lastPartSize = 0; 
    static long numParts = 0; 
    static int lastPartNumber = 0; 
    static string[] hash; 
    static Queue<byte[]> partQueue = new Queue<byte[]>();

    public Encryption(string _filename, long _partSize)
    {
        try
        {
            originalFile = new FileInfo(@_filename);
            partSize = _partSize;

            numParts = originalFile.Length / partSize; 
            lastPartSize = originalFile.Length % partSize; 

            if (lastPartSize != 0)
            {
                numParts++;
            }
            else if (lastPartSize == 0)
            {
                lastPartSize = partSize;
            }

            lastPartNumber = (int)numParts - 1;

            hash = new string[numParts];
        }
        catch (FileNotFoundException fe)
        {
            Console.WriteLine("Error: {0}\nStackTrace: {1}", fe.Message, fe.StackTrace);
            return;
        }
        catch (Exception e)
        {
            Console.WriteLine("Error: {0}\nStackTrace: {1}", fe.Message, fe.StackTrace);
        }
    }

    private void readFromFile()
    {
        try
        {
            using (FileStream fs = new FileStream(originalFile.FullName, FileMode.Open, FileAccess.Read))
            {
                for (int i = 0; i < numParts; i++)
                {                        
                    long len = 0;

                    if (i == lastPartNumber)
                    {
                        len = lastPartSize;
                    }
                    else
                    {
                        len = partSize;
                    }                            

                    byte[] part = new byte[len];                

                    fs.Read(part, 0, (int)len);

                    partQueue.Enqueue(part);

                    part = null;
                }
            }
        }   
        catch(Exception e)
        {
            Console.WriteLine("Error: {0}\nStackTrace: {1}", fe.Message, fe.StackTrace);
        }    
    }

    private static void hashToArray()
    {
        try
        {
            SHA256Managed sha256HashString = new SHA256Managed(); 
            int numPart = 0;

            while (numPart < numParts)
            {
                long len = 0;
                if (numPart == lastPartNumber)
                {
                    len = lastPartSize;
                }
                else
                {
                    len = partSize;
                }

                hash[numPart] = sha256HashString.ComputeHash(partQueue.Dequeue()).ToString();

                numPart++;
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("Error: {0}\nStackTrace: {1}", fe.Message, fe.StackTrace);
        }
    }

    private void hashWrite()
    {
        try
        {
            Console.WriteLine("\nResult:\n");                
            for (int i = 0; i < numParts; i++)
            {
                Console.WriteLine("{0} : {1}", i, hash[i]);
            }
        }
        catch(Exception e)
        {
            Console.WriteLine("Error: {0}\nStackTrace: {1}", fe.Message, fe.StackTrace);
        }
    }

    public void threadsControl()
    {
        try
        {
            Thread readingThread = new Thread(readFromFile);
            Thread calculateThread = new Thread(hashToArray);

            readingThread.Start();
            calculateThread.Start();

            readingThread.Join();
            calculateThread.Join();

            hashWrite();
        }
        catch (Exception e)
        {
            Console.WriteLine("Error: {0}\nStackTrace: {1}", fe.Message, fe.StackTrace);
        }
    }
}
类加密
{
静态文件信息原始文件;
静态长零件尺寸=0;
静态长lastPartSize=0;
静态长numParts=0;
静态int lastPartNumber=0;
静态字符串[]散列;
静态队列partQueue=新队列();
公共加密(字符串\u文件名,长\u部分大小)
{
尝试
{
originalFile=新文件信息(@_文件名);
零件尺寸=_零件尺寸;
numParts=原始文件长度/零件尺寸;
lastPartSize=原始文件。长度%partSize;
如果(lastPartSize!=0)
{
numParts++;
}
else if(lastPartSize==0)
{
lastPartSize=零件尺寸;
}
lastPartNumber=(int)numParts-1;
哈希=新字符串[numParts];
}
捕获(FileNotFoundException fe)
{
WriteLine(“错误:{0}\n堆栈跟踪:{1}”,fe.Message,fe.StackTrace);
回来
}
捕获(例外e)
{
WriteLine(“错误:{0}\n堆栈跟踪:{1}”,fe.Message,fe.StackTrace);
}
}
私有void readFromFile()
{
尝试
{
使用(FileStream fs=newfilestream(originalFile.FullName,FileMode.Open,FileAccess.Read))
{
对于(int i=0;i
在编写此类代码之前,您应该阅读一些有关.NET内部结构的书籍。你对.NET内存模型的理解是完全错误的,这就是为什么你会犯这样的错误<如果您关心您的资源,尤其是在处理数组时,代码>OutOfMemoryException很少发生

您应该知道,在.NET运行时中,引用对象有两个堆,基本堆和堆,它们之间最重要的区别是LOH即使在垃圾收集之后也不会被压缩

您应该知道,所有的阵列,即使是小的阵列,都将进入LOH,并且内存消耗非常快。您还应该知道,这一行:

part = null;
马上。更糟的是,这行根本不做任何事情,因为您仍然有一个引用您在队列中读取的文件的部分。这就是你的记忆力衰退的原因。您可以尝试在每次散列计算后调用
GC
来解决此问题,但这是强烈建议的解决方案

您应该重写您的算法(这是非常简单的
生产者/消费者
模式),而不必同时将整个文件内容存储在内存中。这非常简单-只需将
部分
变量移出静态字段,并将下一个文件部分读入其中。在代码中引入(或)而不是队列,并在读取文件的下一部分后立即计算下一个散列

我记录