2017-01-18 23 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 =ソフトヒープリミット= 128mしかし、dalvikvm gc concurrentは同じことをしています – Dark

答えて

1

簡潔に言えば、あなたは運が悪いかもしれません

でも、試してみることができます。

すべてのグラフィカルプログラムと同様に、格納されたアセットはヒープに圧倒されることがあります。したがって、パフォーマンスを向上させる最善の方法は、はコンテンツマネージャから必要なものだけを読み込むことです。あなたのプログラムがガベージコレクションに遅れていることを考えれば、あなたが資産を使い終わったときにあなたがヒップに必要以上に多くを読み込むことなく解放することができます。だから、GC時間が近づくと、取ったヒープの77%をパージしなければならず、あなたのコードがそのメモリを要求するときにそれを再割り当てする必要があります。

どのように修正する必要がありますか?

おそらく、メモリマネージャを作成する必要があります。コンテンツマネージャへの静的な参照を保持しますが、ヒープに読み込むアセットを要求するメソッドがあります。これにより、余分なヒープ使用をなくすことができますが、ヒープからのこれらのアセットをクリーンアップまたは置換するロジックも含める必要があります。 ガベージコレクションは避けたいが、最適化する必要はありません。以前は変更されていないアセット(テクスチャ、グラフィックス、データ...)をメモリマネージャに保存できるため、いつでもnewオブジェクトの作成を呼び出すのに疲れてしまいます。これにより、不要なヒープ充填を回避し、ガベージコレクションの負担を軽減できます。

グラフィックプログラムによるメモリ管理は難しいことがありますが、これが正しい方向に向けることを望みます。

関連する問題