ユーザーはファイル名とブロックサイズを指定します。元のファイルは、ユーザーブロックサイズ(最後のブロックを除く)のブロックに分割されます。各ブロックについて、ハッシュ関数SHA256
を計算し、コンソールに書き込みます。配列のメモリリークc#
これは2つのスレッドを持つプログラムです。最初のスレッドは元のファイルを読み込み、ブロックのバイト配列をキューに入れます。 2番目のスレッドは、ブロックのバイト配列をキューから削除し、ハッシュを計算します。
最初の反復メモリは、プログラムが完了するまで処理されません。
次回の反復では、メモリが正常に割り当てられ、処分されます。
したがって、次の部分配列の読み込みでは、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);
}
}
}
あなたの質問は何ですか? –
なぜ最初の反復メモリは処分されないのですか?そして、これを解決する方法は? –
私はあなたの質問を理解するか分からない。また、スレッドを手動で処理する代わりに、[タスク](https://msdn.microsoft.com/en-us/library/dd537609(v = vs.110).aspx)でこれらをラップするのはなぜですか? –