MD5 Checksum 질문

1개의 파일을 읽을 때는 문제가 없습니다.
다만 2개 이상 부터 메모리 누수가 나는거 같습니다.

해결법이 있을까요?

어떻게 코드를 구현하셨는지 말씀해주시지 않으면 추측에 의거해서 답을 해드리거나 대신 코딩해드려야 하는 상황이 됩니다.

1 Like
*OpenFileDialog ofd = new OpenFileDialog();
String filePath = "text.txt";

byte[] btAscii = File.ReadAllBytes(filePath);
byte[] btHash = MD5.Create().ComputeHash(btAscii);
label5.Text = BitConverter.ToString(btHash).Replace("-", "").ToLower();

이런 식으로 했습니다

1 Like

메모리 누수가 난다는게 어떤 근거로 난다는건지 알수있을까요??
아래 코드로 n번 반복해보았지만 누수되는부분을 찾을수가 없어서 그렇습니다…

1 Like

foreach를 사용하여 text1.txt~text5.txt 했을 때 메모리 누수가 납니다

1 Like

단순히 코드만 봤을 때는 OpenFileDialog 말고는 짚이는게 없어 보입니다.

이 클래스를 사용하셨다면 얘는 IDisposable 인터페이스를 갖기 때문에 Dispose() 함수 호출이 필요합니다.

2 Likes

메모리 누수라기 보다, 파일의 모든 내용을 메모리에 불러오는 동작이 우선 문제가 됩니다.

byte[] btAscii = File.ReadAllBytes(filePath);

이렇게 하면, 예를 들어 10MiB 정도의 파일을 메모리에 모두 읽어 들이므로 일단 10MiB 내외로 메모리를 사용하기 시작할겁니다.

그 다음,

btHash = MD5.Create().ComputeHash(btAscii);

이 코드에서 추가로 MD5 해싱 연산을 위해 추가 메모리 공간을 사용할 것입니다. btAscii 자체의 크기가 크다면 당연히 추가 메모리 공간이 필요할 것입니다.

이 코드에서 문자열 저장을 위해 추가 메모리를 사용할 것입니다.

당연히 위의 코드가 여러번 반복해서 실행된다면 메모리를 많이 사용할 것입니다.

닷넷이 가비지 컬렉션을 지원하는 런타임 환경인 것은 맞으나, 가비지 컬렉션이 아무 때나 돌면 제 성능을 낼 수는 없고, 일정 선을 넘기 전까지는 메모리를 굳이 회수하려고 하지 않기 때문에 마치 메모리 누수가 있는 것처럼 보일 수 있습니다.

만약 메모리 사용량이 급증하는 것이 문제라고 생각한다면, 위와 같이 나이브한 코딩 방식 대신 System.IO.Stream 등을 활용해서 조금씩 데이터를 읽는 방법으로 코드를 고치거나, 너무 크기가 큰 파일은 취급하지 않도록 조건문을 달아 두시는게 필요할 것 같습니다.

예를 들면, 다음과 같이 고쳐쓸 수 있을 것입니다.

OpenFileDialog ofd = new OpenFileDialog();
String filePath = "text.txt";

using (var fileStream = File.OpenRead(filePath))
using (var hash = MD5.Create())
{
	byte[] btHash = hash.ComputeHash(fileStream);
	label5.Text = BitConverter.ToString(btHash).Replace("-", string.Empty).ToLowerInvariant();
}

덧) .NET 6 기준으로는 ComputeHash의 async 버전인 ComputeHashAsync도 있습니다.

참고: md5 - Computing MD5SUM of large files in C# - Stack Overflow

3 Likes

답변 감사합니다 많은 도움이 되었습니다!

2 Likes