使用MonoGame API在C#中编写应用程序。 这些应用程序是专为Android设计的,但我决定优化它一点,所以我将它移植到Windows以使其与CLRProfiler一起工作,我发现Heap在77%的Microsoft.Xna.Framework.Content.ContentManager->系统。字节[]。有没有办法在我的应用程序中避免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 :(得分:1)
简而言之,你可能会失去运气。
但是,你可以尝试一些事情。
与每个图形程序一样,存储的资产可能压倒堆。因此,提高性能的最佳方法是仅从内容管理器中加载您需要的内容。考虑到您的程序滞后于垃圾收集,希望您在完成资产时不需要释放它就可以将更多的内容加载到堆中。因此,当GC时间到来时,它必须清除占用的77%的堆,并在代码请求该内存时重新分配它。
那你应该怎么解决呢?
您可能需要编写内存管理器。保持对内容管理器的静态引用,但是有方法可以请求将资源加载到堆中。这应该有望减少任何额外的堆使用,但是当你完成它们时,你还应该包括从堆中清除或替换这些资产的逻辑。 您不希望避免垃圾收集,但要对其进行优化。您可以随时调用new
对象,因为您可以存储以前未更改的资源,我会感到厌倦(纹理,图形,数据......)在你的记忆管理器中。这可以避免不必要的堆填充并防止垃圾回收的负担。
使用图形程序进行内存管理可能会非常棘手,但我希望这有助于您确定正确的方向。