2017-01-18 1 views
1

응용 프로그램이 MonoGame API를 사용하여 C#으로 작성되었습니다. 이 응용 프로그램은 안드로이드 용으로 설계되었지만 Windows 용으로 포팅하여 CLRProfiler와 함께 사용할 수 있도록 포트를 약간 최적화하기로 결정했습니다. 힙이 77 %에 있음을 알았습니다. Microsoft.Xna.Framework.Content.ContentManager-> System .바이트[]. 내 앱에서 GC 수집을 피할 수있는 방법이 있습니까? 문제가있는 부분은 다음과 같습니다.콘텐츠 관리자가 많은 힙 크기를 사용하는 이유는 무엇입니까?

using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Graphics; 
using Microsoft.Xna.Framework.Input; 

namespace Game1 
{ 
    public struct FPS_counter 
    { 
     float fps_from; 
     int fps; 
     public int fps_toshow; 
     public float in_Secs; 

     public void add_frame() 
     { 
      fps_from += in_Secs; //(float)gameTime.ElapsedGameTime.TotalSeconds; 
      if (fps_from > 1) 
      { 
       fps_toshow = fps; 
       fps = 0; 
       fps_from = 0; 
      } 
      fps++; 
     } 
    } 

    public struct numbers 
    { 

     public Texture2D[] texture; 
     public int num1, num2; 
     public Vector2 pos1, pos2, origin; 
     public int number; 

     public void update() 
     { 

      num1 = 0; 
      num2 = 0; 
      int nuu = number; 
      if (nuu > 10) 
      { 
       for (int i = 0; i < 10; i++) 
       { 
        if (number >= (i * 10)) 
        { 
         num1 = i; 
        } 
        else break; 
       } 
      } 
      nuu -= num1 * 10; 
      for (int i = 0; i < 10; i++) 
      { 
       if (nuu >= i) 
       { 
        num2 = i; 
       } 
       else break; 
      } 

     } 
     public void draw() 
     { 
      if (number > 9) Game1.spriteBatch.Draw(texture[num1], pos1, origin: origin); 
      Game1.spriteBatch.Draw(texture[num2], pos2, origin: origin); 
     } 
    } 

    public class Game1 : Game 
    { 
     GraphicsDeviceManager graphics; 
     public static SpriteBatch spriteBatch; 
     FPS_counter counter; 
     numbers Numb; 

     public Game1() 
     { 
      graphics = new GraphicsDeviceManager(this); 
      Content.RootDirectory = "Content"; 
      counter = new FPS_counter(); 
      Numb = new numbers(); 
     } 

     protected override void Initialize() 
     { 
      base.Initialize(); 
     } 

     protected override void LoadContent() 
     { 
      spriteBatch = new SpriteBatch(GraphicsDevice); 
      Numb.texture = new Texture2D[10]; 
      for (int i = 0; i < 10; i++) 
      { 
       Numb.texture[i] = Content.Load<Texture2D>(("" + i)); 
      } 
      Numb.num1 = 0; 
      Numb.num2 = 0; 
      Numb.number = 22; 
      Numb.pos1 = new Vector2(250, 50); 
      Numb.pos2 = new Vector2(270, 50); 
      Numb.origin = new Vector2(10, 10); 

     } 

     protected override void UnloadContent() 
     { 
     } 

     protected override void Update(GameTime gameTime) 
     { 
      if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape)) 
       Exit(); 

      base.Update(gameTime); 
     } 

     protected override void Draw(GameTime gameTime) 
     { 
      GraphicsDevice.Clear(Color.CornflowerBlue); 

      spriteBatch.Begin(); 
      counter.in_Secs = (float)gameTime.ElapsedGameTime.TotalSeconds; 
      counter.add_frame(); 
      Numb.number = counter.fps_toshow; 
      Numb.update(); 
      Numb.draw(); 
      spriteBatch.End(); 

      base.Draw(gameTime); 
     } 
    } 
} 

죄송하지만 영어는 죄송하지만 폴란드입니다.

+0

콘텐츠 관리자가 다루는 콘텐츠 즉 저작물을 고려할 때 많은 양의 힙 공간을 차지한다는 것은 놀라운 일이 아닙니다. 그것은 예상된다. 당신의 경우에 이것이 문제라고 생각하는 이유가 있습니까? –

+0

Gc 컬렉션은 매 경기마다 15 분씩 지연됩니다. 그렇습니다. – Dark

+0

나는 이것들을 시도한다 : MONO_GC_PARAMS = nursery-size = 32m MONO_GC_PARAMS = soft-heap-limit = 128m 그러나 dalvikvm gc concurrent가 동일을하고있다 – Dark

답변

1

간단히 말해 운이 좋지 않을 수도 있습니다..

하지만 시도 할 수있는 것들이 있습니다.

모든 그래픽 프로그램에서와 마찬가지로 저장된 자산은 힙을 압도 할 수 있습니다. 따라서 성능을 향상시키는 가장 좋은 방법은 콘텐츠 관리자에서 필요한 것을로드하는 것입니다. 입니다. 프로그램이 가비지 수집에 뒤쳐져 있다고 가정하면, 자산을 다 처리 할 때 힙에 필요한 것 이상을로드하지 않고 힙에로드하는 것이 좋습니다. 따라서 GC 시간이 다가 왔을 때 77 %의 힙을 제거해야하고 코드가 메모리를 요청할 때이를 재 할당해야합니다.

어떻게 수정해야합니까?

아마도 메모리 관리자를 작성해야합니다. 콘텐츠 관리자에 대한 정적 참조를 유지하지만 힙에 에셋을로드하도록 요청하는 메소드가 있어야합니다. 이렇게하면 여분의 힙 사용을 줄여야하지만 힙의 이러한 자산을 정리하거나 교체하는 논리도 포함시켜야합니다. 가비지 수집을 피하고 싶지는 않지만 최적화하십시오. 이전에 변경되지 않은 자산 (텍스처, 그래픽, 데이터 ...)을 메모리 관리자에 저장할 수 있기 때문에 언제든지 new 오브젝트 생성을 호출하는 데 지쳐있었습니다. 이렇게하면 불필요한 힙 채우기가 발생하지 않고 가비지 수집에 대한 부담을 피할 수 있습니다.

그래픽 프로그램을 사용한 메모리 관리는 까다로울 수 있지만 올바른 방향으로 사용자를 안내하는 데 도움이되기를 바랍니다.

관련 문제