Published using Google Docs
.NET 메모리 사용 – 성능 향상을 위한 7가지 팁
Updated automatically every 5 minutes

출처: https://www.red-gate.com/products/dotnet-development/ants-performance-profiler/resources/net-memory-usage-7-tips-for-better-performance 

크기를 미리 알 수 없는 경우 배열 대신 list를 사용하자

Megha Maheshwari | www.linkedin.com/in/formegha | www.quora.com/megha-maheshwari

데이터를 추가하거나 제거하려면 배열 대신 list를 사용하자. list는 동적으로 증가하고 필요한 것보다 더 많은 공간을 예약할 필요가 없지만 배열의 크기 조정은 비용이 많이든다. 이는 향후 성장 패턴과 향후 액세스 패턴이 무엇인지 알고 있을 때 특히 유용하다.

GC.Collect()를 명시적으로 호출하지 말자.

Rakesh Nhalil Edavalath | https://in.linkedin.com/pub/rakesh-nhaliledavalath/85/402/588

가비지 컬렉터는 애플리케이션의 .NET 메모리 사용량 및 OS 메모리 압박과 같은 요소의 영향을 받아 적절한 실행 시간을 계산하는 데 매우 능숙하다. 명시적으로 호출할 필요는 거의 없다.

더 심각한 문제는 가비지 컬렉션을 실행하면 애플리케이션 성능에 영향을 미친다는 점이다. 성능에 미치는 영향은 가비지 컬렉션에서 살아남는 메모리의 개체 수에 비례하므로 가비지 수집기를 필요 이상으로 일찍 또는 자주 실행하면 성능이 심각하게 저하될 수 있다.

.NET 가비지 수집기(GC) 및 애플리케이션 속도를 저하시키는 일시 중지를 유발할 수 있는 경우에 대해 알아보자.

Matt Warren | @matthewwarren | www.mattwarren.org

시간이 지남에 따라 .NET GC는 더욱 발전했지만(특히 .NET 4.5의 백그라운드 서버 GC 모드) GC가 애플리케이션 성능에 부정적인 영향을 미칠 수 있는 상황이 여전히 있다.

이러한 상황을 감지하는 방법과 더 중요한 것은 이를 해결하는 방법을 이해하는 것이 유용한 기술이다. 예를 들어, 많은 애플리케이션에는 다른 작업보다 성능이 더 중요한 작업이 있으며, 가비지 컬렉션이 덜 중요한 기간 동안 실행되는 것이 바람직할 수 있다. GCLatencyMode를 설정하면 가비지 컬렉터가 이러한 시간 동안 실행을 보다 보수적으로 선택하도록 요청하는 유용한 방법이 있다.

.NET 메모리 사용 및 성능 문제를 방지하기 위해 메모리 누수 수정

Cosimo Nobile | @cosimo_nobile

메모리 누수는 성능에도 영향을 미칠 수 있다. 메모리 누수가 의심되면 성능 모니터에서 대상 프로세스에 대해 관리되는 메모리와 관리되지 않는 메모리 사용량을 플로팅하여 조사를 시작하는 경우가 많다. 나는 이것이 종종 메모리 누수의 수와 특성, 그리고 시간에 따라 또는 외부 입력에 대한 응답으로 변경되는 방식에 대한 예비 및 정성적 지표를 제공할 수 있음을 발견했다.

예를 들어 한 번은 다음과 같이 시작했다.

.NET 메모리 사용량 그래프, 관리되지 않는 메모리 사용량 증가 추세, 일정한 기울기 및 여러 단계 점프를 보여줌

이것은 프로세스가 관리되지 않는 메모리를 누수하고 있음을 확인했다. 또한 그래프가 일정한 기울기 기울기 외에도 임의의 단계를 보여주기 때문에 잠재적으로 여러 가지 원인이 있을 수 있다는 몇 가지 초기 징후를 제공했다. 지속적인 누출 원인을 수정하면 아래와 같은 결과가 나타난다.

지속적인 누수를 수정한 후 .NET 메모리 사용량 그래프가 일정한 기울기가 아닌 임의의 단계로 증가한다.

경사면은 분명히 사라졌지만 가끔씩 무작위 계단이 여전히 존재했습니다. 이 문제를 찾기가 더 어려웠지만, 이 기능을 비활성화한 후 가끔씩 스파이크가 있는 평평한 트레이싱을 얻었기 때문에 곧 어떤 구성 요소가 원인인지 명확해졌습니다:

추세가 평평하고 가끔 급증하는 .NET 메모리 사용량 그래프

마지막으로 식별된 구성 요소에서 누수를 찾아 수정한 후 다음 그래프를 통해 모든 문제가 발견되고 해결되었다는 확신이 생겼다.

최종 .NET 메모리 사용량 그래프, 평면 기울기 및 훨씬 더 작은 피크 포함

가능하다면 원하는 크기를 미리 할당하자

Greg Young | @gregyoung

메모리 스트림, 목록, 사전과 같은 많은 객체는 필요에 따라 크기가 두 배가 되어 복사 및 할당이 낭비된다. 목록에 100,000개의 항목이 포함될 것이라는 것을 알고 있다면 나중에 문제가 발생하지 않도록 초기화하자.

중복 문자열 참조 문제 방지

문자열 참조 중복은 메모리를 많이 차지하는 주요 성능 문제 중 하나이다. 문자열 인터닝은 런타임에 동일할 가능성이 높은 문자열을 많이 생성하는 경우 유용한 솔루션이다. 아래와 같이 IsInterned를 호출하여 인턴된 문자열이 존재하는지 확인한다:

class Program
{
        
static void Main()
        {
                
// A.
                
// String generated at runtime.
                
// Is not unique in string pool
                
string s1 = new StringBuilder().Append("cat").
                Append(
" and dog").ToString();
                
// B.
                
// Interned string added at runtime.
                
// Is unique in string pool.
                
string s2 = string.Intern(s1);
        }
}

                                                

내 자신의 벤치마킹은 문자열 비교가 항상 참일 때 문자열 인턴이 성능을 4배 이상 향상시킬 수 있음을 보여주었다.

관리되지 않는 리소스 폐기

Rob Karatzas | @ebiztutor

파일 I/O, 네트워크 리소스, 데이터베이스 연결 등은 사용이 완료되면 가비지 수집기가 처리할 때까지 기다리지 않고 폐기해야 한다. 코드에서 메모리를 사용하는 속도에 따라 밀리초에서 몇 분까지 걸릴 수 있다. 많이 사용하지 않으면 시간이 오래 걸린다.

이러한 유형의 리소스는 일반적으로 개체 사용이 완료되면 관리되지 않는 리소스를 해제할 수 있도록 IDisposable 인터페이스를 구현한다.

이상적으로는 'using' {..} 블록을 사용하여 개체가 범위를 벗어나면 자동으로 삭제하거나 수동으로 Dispose()를 호출하도록 한다.