我正在使用xna开发第一款适用于Windows Phone 7的游戏。 经过一些测试后,我注意到游戏动画的短暂减速并实施了一些性能测试,但未能完全消除减速。 现在我创建了一个空项目,其中只有DrawableGameComponent继承类绘制有关runsslow标志,Draw / Update时间(传递给方法)以及垃圾收集器是否正在运行的文本。 奇怪的是,即使使用这种简约代码,延迟似乎每1至5秒出现一次。延迟时我指的是绘图时间而不是33毫秒> 50毫秒。有时甚至runsslow标志也会在这个简约的项目中设置。 根据我的实验,垃圾收集器似乎不是这个的主要原因,因为他的执行要少得多。 方便也设置为飞行模式,所以没有沟通。
更新代码:
public override void Update(GameTime gameTime)
{
elapsedTime += gameTime.ElapsedGameTime;
timeSpanUpdate.Add(gameTime.ElapsedGameTime.TotalMilliseconds);
if (elapsedTime.TotalMilliseconds >= timeToElapseForVisualisation)
{
//update the values messured
elapsedTime -= TimeSpan.FromMilliseconds(timeToElapseForVisualisation);
//get the values we are interested in
double sum = 0;
maxUpdateTime = int.MinValue;
foreach (double val in timeSpanUpdate)
{
sum += val;
maxUpdateTime = (int)Math.Max(maxUpdateTime, val);
}
averageUpdateTime = (int)(sum / timeSpanUpdate.Count);
timeSpanUpdate.Clear();
sum = 0;
maxDrawTime = int.MinValue;
foreach (double val in timeSpanDraw)
{
sum += val;
maxDrawTime = (int)Math.Max(maxDrawTime, val);
}
averageDrawTime = (int)(sum / timeSpanDraw.Count);
timeSpanDraw.Clear();
}
if (gameTime.IsRunningSlowly)
{
runsSlow = true;
timeToShowRunsslowRemaining = timeToShow;
}
else if (timeToShowRunsslowRemaining > 0)
{
timeToShowRunsslowRemaining -= gameTime.ElapsedGameTime.TotalMilliseconds;
}
else
{
runsSlow = false;
}
}
抽奖代码:
//we use stringbuilders as strings passed to drawstring can induce the gc
private StringBuilder drawText = new StringBuilder("Draw max: ");
private StringBuilder updateText = new StringBuilder("Update max: ");
private StringBuilder runsslowYes = new StringBuilder("runsslow: yes");
private StringBuilder runsslowNo = new StringBuilder("runsslow: no");
public override void Draw(GameTime gameTime)
{
DateTime now = DateTime.Now;
timeSpanDraw.Add((now - lastDrawCall).TotalMilliseconds);
lastDrawCall = now;
drawText.Remove("Draw max: ".Length, drawText.Length - "Draw max: ".Length);
drawText.Append(maxDrawTime);
updateText.Remove("Update max: ".Length, updateText.Length - "Update max: ".Length);
updateText.Append(maxUpdateTime);
spriteBatch.Begin();
if (maxDrawTime >= thresholdMaxDelays)
{
spriteBatch.DrawString(spriteFont, drawText, drawTextPos, Color.Red);
}
else
{
spriteBatch.DrawString(spriteFont, drawText, drawTextPos, Color.White);
}
if (maxUpdateTime >= thresholdMaxDelays)
{
spriteBatch.DrawString(spriteFont, updateText, updateTextPos, Color.Red);
}
else
{
spriteBatch.DrawString(spriteFont, updateText, updateTextPos, Color.White);
}
if (runsSlow)
{
spriteBatch.DrawString(spriteFont, runsslowYes, runsslowTextPos, Color.Red);
}
else
{
spriteBatch.DrawString(spriteFont, runsslowNo, runsslowTextPos, Color.White);
}
spriteBatch.End();
base.Draw(gameTime);
}
我注意到的是它并不是一直存在。
答案 0 :(得分:2)
这可能有所帮助(http://www.gavpugh.com/2010/04/01/xnac-avoiding-garbage-when-working-with-stringbuilder/) 即使使用StringBuilder,垃圾收集器仍然可能出错。 上面的链接解释了一些Append调用definetly产生垃圾。它还有一个类,有助于使用stringBuilder附加产生更少的垃圾。
另外(http://devblog.andyc.org/2011/05/garbage-control/)在字符串构建器上使用无垃圾包装器。
您是否尝试过使用CLR Profiler查看是否存在内存压力?