이것은 내 첫 번째 게시물입니다. XNA를 사용하여 Visual Studio 2010에서 게임을 만들고 있는데, 거대한 메모리 누수가 발생했습니다. 내 게임은 17k 램을 사용하여 시작하고 10 분 후에는 65k 개까지 진행됩니다. 일부 메모리 프로파일 러를 돌렸고 String 객체의 새 인스턴스가 생성되고 있지만 라이브는 아닙니다. String의 실제 인스턴스 양은 전혀 변경되지 않았습니다. 또한 Char [] (인스턴스에서 기대하는), Object [] 및 StringBuilder 인스턴스를 만듭니다. 내 게임은 꽤 새롭지 만 여기에 게시 할 코드가 너무 많습니다. 나는 살아 있지 않은 경우를 제거하는 방법을 모릅니다. 제발 도와주세요!C#/XNA Giant Memory Leak
답변
C#에서는 메모리 누수가 없습니다 (또는 잘 모르지만, 그들은 매우 어려움). 당신이 겪고있는 것은 정상입니다. 가비지 수집기는 메모리를 수집해야하는 것처럼 "느끼지"않으므로 그렇게하지 않습니다. 메모리가 부족하면 가비지 수집이 발생합니다. 인 경우 인 경우 string
에 대한 불필요한 참조를 보관하지 않아도됩니다.
강제로 GC주기를 사용하려면 GC.Collect()
을 사용하십시오.
게임에서'GC.Collect'를 사용하는 것은 좋은 생각이 아닙니다. 게임 루프 내에서 객체 풀링을 사용하고 동적 인 할당을 피하는 것이 좋습니다. –
XNA의 일부는 관리 코드가 아니므로 GC가 작동하지 않습니다. 이렇게 : http://stackoverflow.com/questions/3364481/outofmemory-exception-when-drawing-cube –
교육받은 추측을 넘어서는 충분한 정보를 게시하지 않았습니다.
당신이 당신의 그리기 방법이 같은 일을하는 경우 :
spriteBatch.DrawString(font, "Score: " + score, location, Color.Black);
spriteBatch.DrawString(font, "Something else: " + foo, overHere, Color.Black);
spriteBatch.DrawString(font, "And also: " + bar, overThere, Color.Black);
다음
이러한 호출은 각각 허리 뒤에 새로운 string
및 StringBuilder
객체가 실행할 때마다 생성됩니다 여기 내 추측이다. 그들은 귀하의 Draw
방법에 있기 때문에 각각 초당 60 회씩 실행됩니다. 그것은 할당되는 많은 임시 객체입니다!
이 경우를 확인하려면 CLR 프로파일 러를 사용하십시오. 이미 해본 것처럼 들리는군요.
이것은 실제로 "누출"이 아닙니다. 가비지 수집기가 결국에는이를 정리합니다.이 할당 패턴은 게임에서 바람직하지 않습니다. 게임에서 가비지 수집을 다루는 두 가지 방법에 대한 내용은 this blog post을 참조하십시오. 방법 1은 일반적으로 더 쉽고 더 나은 결과를 제공하므로 여기에서 설명하겠습니다.
이 시점에서 PC의 GC가 충분히 빠르므로 과 같은 할당이 실제로과 관련이 없다고 언급 할 가치가 있습니다. GC는 매우 적은 오버 헤드로 작은 객체 (예 : 임시 문자열)를 정리합니다.
반면 Xbox 360에서는 이와 같이 정기적으로 소량의 쓰레기를 생성해도 심각한 성능 문제가 발생할 수 있습니다. (WP7에 대해서는 잘 모르겠지만, 개인적으로 Xbox처럼 취급 할 것입니다.)
어떻게 수정합니까?
대답은 간단하다 : DrawString
가 string
대신에 StringBuilder
의 인스턴스를 받아 들일 것입니다. StringBuilder
의 인스턴스 하나를 만든 다음 사용자 지정 문자열을 구성해야 할 때마다 다시 사용하십시오.
숫자 또는 다른 개체를 암시 적으로 또는 ToString()
메서드로 문자열로 변환하면 할당이 발생합니다. 따라서 할당을하지 않고 StringBuilder
에 추가 할 사용자 지정 코드를 작성해야 할 수 있습니다.여기
은 할당하지 않고 내가 문자열로 정수를 추가하기위한, 확장 메서드의 형태로 사용 하나입니다
public static class StringBuilderExtensions
{
// 11 characters will fit -4294967296
static char[] numberBuffer = new char[11];
/// <summary>Append an integer without generating any garbage.</summary>
public static StringBuilder AppendNumber(this StringBuilder sb, Int32 number)
{
bool negative = (number < 0);
if(negative)
number = -number;
int i = numberBuffer.Length;
do
{
numberBuffer[--i] = (char)('0' + (number % 10));
number /= 10;
}
while(number > 0);
if(negative)
numberBuffer[--i] = '-';
sb.Append(numberBuffer, i, numberBuffer.Length - i);
return sb;
}
}
기술적으로 numberBuffer가 필요하지 않습니다. (캐시 히트를 줄이기 위해 더 빨리) 한 번에 1 개의 char을 추가하십시오. 크기 조정이 걱정되면 sb.EnsureCapacity (sb.Length + 16)를 사용하여 캐시 라인 정렬을 유지하십시오 (16). – GGulati
아, 와우,이게 너무 의미가 있습니다. 내가 할 수있는 한 빨리 이걸 시도 할께. 고마워. – Kirbyfanner
@GGulati 캐릭터에 'Append'를 호출하는 것이 버퍼에서 문자열을 만들고 그곳으로 떨어 뜨리는 것보다 약간 더 낫습니다 ** 알고리즘은 오른쪽에서 왼쪽으로 문자열을 구성합니다 **. 운동으로 왼쪽에서 오른쪽으로 알고리즘을 떠날 것입니다;) 더 나아가 'EnsureCapacity'에 대해 걱정할 필요가 없습니다. 요점은 버퍼를 재사용하는 것입니다. 따라서 용량을 늘리는 것은 한 번 발생합니다. 그리고 CPU 시간은 아주 작은 차이입니다. 이는 특정 GC 최적화입니다. 상단에 불필요한 최적화를 추가하는 나쁜 형식. –
- 1. getmem memory leak, delphi
- 2. AVCaptureStillImageOutput outputSettings memory leak
- 3. getpwnam_r memory leak
- 4. sun.font.TrueTypeFont Memory Leak?
- 5. UITextView memory leak
- 6. web.py memory leak
- 7. pthread_create memory leak?
- 8. Silverlight ChildWindow Memory Leak
- 9. javascript jsonp memory leak
- 10. PHP Imagick memory leak
- 11. NSArray sortedArrayUsingSelector memory leak
- 12. TreeView.Items.Filter Memory Leak, HELP!
- 13. Perl substr memory leak
- 14. StructureMap ObjectFactory.Reset memory leak?
- 15. Msxml3 - Memory leak
- 16. Javascript responseXML memory leak
- 17. Zeromq memory leak (pyzmq)
- 18. pthread_create memory leak
- 19. sqlite memory leak
- 20. mod_perl memory leak
- 21. Unsolvable memory leak IPhone
- 22. Magento memory leak
- 23. Android Memory Leak new Thread()
- 24. socket.io redis and memory leak
- 25. Android Memory Leak - 내부 클래스
- 26. iphone copyWithZone memory leak - 도움이 필요합니다.
- 27. Memory Leak, PHP 및 MySQL Blob 스트리밍 파일 디버깅
- 28. MemoryStream leak
- 29. NSIndexPath Leak
- 30. Tomcat Server Memory Leaks
나는 65K는 "거대한 메모리 누수"이라고 생각 모르겠어요. 30 년 전부터 개인용 컴퓨터에 거의 맞출 수있었습니다. 그것이 650MB까지 불고 있다면 나는 조금 걱정할지도 모른다. –
나는 당신이 심지어 17K 호스트 프로세스 크기로 내려갈 수 있다고 생각하지 않기 때문에 65,000K까지 의미해야한다고 생각합니다. 그럼에도 불구하고 65M은 현대 표준으로는 그다지 크지 않습니다. –
좋아요, 괜찮 으면 그걸 미끄러 뜨리겠습니다. 때때로 재설정됩니다. 정말 고마워! 그리고 예, 나는 65,000k를 의미했습니다. – Kirbyfanner