[C#] C #에서 가비지 수집을 강제하는 모범 사례

내 경험상 대부분의 사람들은 가비지 수집을 강제하는 것이 현명하지 않다고 말할 것 같지만, 0 세대에서 항상 수집되지는 않지만 메모리가 문제가되는 큰 개체로 작업하는 경우에는 수집을 강제해도 괜찮습니까? 그렇게하기위한 모범 사례가 있습니까?



답변

가장 좋은 방법은 가비지 수집을 강제하지 않는 것입니다.

MSDN에 따르면 :

“Collect를 호출하여 가비지 수집을 강제 할 수 있지만 성능 문제가 발생할 수 있으므로 대부분 피해야합니다.”

그러나 Collect () 호출이 부정적인 영향을 미치지 않는지 확인하기 위해 코드를 안정적으로 테스트 할 수 있다면 계속 진행하십시오.

더 이상 필요하지 않을 때 개체가 정리되었는지 확인하십시오. 사용자 정의 개체가있는 경우 “using 문”및 IDisposable 인터페이스 사용을 살펴보십시오.

이 링크에는 메모리 / 가비지 수집 등을 해제하는 것과 관련하여 실용적인 조언이 있습니다.

http://msdn.microsoft.com/en-us/library/66x5fx1b.aspx


답변

이런 식으로보세요. 음식물 쓰레기통이 10 % 일 때 버리는 것이 더 효율적입니까, 아니면 버리기 전에 가득 채우는 것이 더 효율적입니까?

가득 채우지 않으면 외부 쓰레기통을 오가는 시간을 낭비하게됩니다. 이는 GC 스레드가 실행될 때 발생하는 것과 유사합니다. 모든 관리 스레드는 실행되는 동안 일시 중지됩니다. 그리고 내가 착각하지 않으면 GC 스레드를 여러 AppDomain간에 공유 할 수 있으므로 가비지 컬렉션은 모두에 영향을줍니다.

물론, 휴가를 떠날 예정이라면 곧 쓰레기통에 아무것도 추가하지 않을 상황에 처할 수도 있습니다. 그러면 외출하기 전에 쓰레기를 버리는 것이 좋습니다.

이것은 GC를 강제하는 것이 도움이 될 수있는 한 번일 수 있습니다. 프로그램이 유휴 상태이면 할당이 없기 때문에 사용중인 메모리가 가비지 수집되지 않습니다.


답변

가장 좋은 방법은 대부분의 경우 가비지 수집을 강제하지 않는 것입니다. (내가 작업 한 모든 시스템에 가비지 수집을 강제하고 해결하면 가비지 수집을 강제 할 필요가 없어지고 시스템 속도가 크게 빨라지는 밑줄 문제가있었습니다.)

가비지 수집기보다 메모리 사용량에 대해 더 많이 알고 있는 몇 가지 경우있습니다 . 이는 다중 사용자 응용 프로그램이나 한 번에 하나 이상의 요청에 응답하는 서비스에서는 해당되지 않을 수 있습니다.

그러나 일부 배치 유형 처리 에서는 GC보다 더 많이 알고 있습니다. 예를 들어 응용 프로그램을 고려하십시오.

  • 명령 줄에 파일 이름 목록이 제공됩니다.
  • 단일 파일을 처리 한 다음 결과 파일에 결과를 씁니다.
  • 파일을 처리하는 동안 파일 처리가 완료 될 때까지 수집 할 수없는 많은 상호 연결된 개체를 생성합니다 (예 : 구문 분석 트리).
  • 처리 한 파일간에 많은 상태를 유지하지 않습니다 .

당신은 할 수 있습니다 각 파일을 처리 한 후에는 전체 가비지 컬렉션을 강제해야 테스트 (주의 후) 케이스를 만들 수.

또 다른 경우는 일부 항목을 처리하기 위해 몇 분마다 깨어나고 수면 상태를 유지하지 않는 서비스입니다 . 그런 다음 잠들기 직전에 전체 수집을 강제하는 것이 가치 있을 있습니다.

컬렉션 강제를 고려하는 유일한 경우는 최근에 많은 개체가 생성되었고 현재 참조되는 개체가 거의 없다는 것을 알고있을 때입니다.

GC를 강제하지 않고도 이러한 유형에 대한 힌트를 줄 수있을 때 가비지 수집 API를 사용하는 것이 좋습니다.

Rico Mariani의 Performance Tidbits ” 도 참조하십시오.


답변

Rico Mariani 가 제시 한 예가 좋았다고 생각합니다 . 애플리케이션 상태에 큰 변화가있는 경우 GC를 트리거하는 것이 적절할 수 있습니다. 예를 들어 문서 편집기에서 문서가 닫힐 때 GC를 트리거해도 괜찮을 수 있습니다.


답변

절대적인 프로그래밍에 대한 일반적인 지침은 거의 없습니다. 절반의 시간 동안 누군가가 ‘당신이 잘못하고있다’고 말할 때, 그들은 단지 일정량의 교리를 내뿜는 것입니다. C에서는 자체 수정 코드 또는 스레드와 같은 것에 대한 두려움이 있었으며 GC 언어에서는 GC를 강제하거나 GC가 실행되지 않도록합니다.

대부분의 지침과 좋은 경험 법칙 (그리고 좋은 디자인 관행)의 경우처럼, 확립 된 표준을 우회하는 것이 합리적 일 경우는 드뭅니다. 당신은 당신이 사건을 이해하고, 당신의 사건이 정말로 일반적인 관행의 폐지를 요구하고, 당신이 유발할 수있는 위험과 부작용을 이해하고 있음을 확신해야합니다. 그러나 그러한 경우가 있습니다.

프로그래밍 문제는 매우 다양하며 유연한 접근 방식이 필요합니다. 가비지 수집 언어에서 GC를 차단하는 것이 합리적이며 자연스럽게 발생하기를 기다리지 않고 트리거하는 것이 합당한 경우를 보았습니다. 95 %의 경우, 이들 중 하나는 문제에 제대로 접근하지 못했다는 신호가 될 것입니다. 그러나 20 명 중 1 번, 아마도 그것을위한 유효한 사례가있을 것입니다.


답변

나는 가비지 수집을 능가하려고하지 않는 법을 배웠다. 즉, using파일 I / O 또는 데이터베이스 연결과 같은 관리되지 않는 리소스를 다룰 때 키워드 사용을 고수 합니다.


답변

이것이 모범 사례인지 확실하지 않지만 루프에서 많은 양의 이미지로 작업 할 때 (예 : 많은 그래픽 / 이미지 / 비트 맵 개체를 만들고 처리) 정기적으로 GC.Collect를 사용합니다.

나는 GC가 프로그램이 (대부분) 유휴 상태 일 때만 실행되고 집중적 인 루프의 중간에 있지 않을 때만 실행된다는 것을 읽은 것 같아서 수동 GC가 의미가있는 영역처럼 보일 수 있습니다.