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