向256 MB内存的Windows Phone提供应用的最佳实践指导
簡介
為了使得應用能在256 MB的Windows Phone設(shè)備上運行需要進行一些改動。
首先,與512 MB的設(shè)備相比,256 MB手機上的內(nèi)存使用/分配方式是不同的。運行在256 MB上的應用仍然有同等數(shù)量的內(nèi)存(90 MB),但60 MB之后的“工作集”將會被分頁。因此雖然它允許應用最多使用90 MB,應用使用少于60 MB可以運行得更好。第二,256 MB設(shè)備不支持潛在無界的內(nèi)存消耗的計劃任務(wù)。
本文提供了最佳實踐指導和技巧用來滿足60 MB的目標,并且處理其他的小的平臺變化。
Tip #1——總是使用模擬器的256 MB選項測試程序
Windows Phone SDK 7.1.1模擬器使得你可以在256 MB和512 MB內(nèi)存之間進行選擇。一旦你選擇了其中一個模擬器將分配相應大小的內(nèi)存(與實體機一樣)。
建議最好的做法是總是使用256 MB作為模擬器部署所有應用程序的默認選擇。使用這種方法確保在256 MB的內(nèi)存上應用程序的任何問題在部署之前就能解決。另外,雖然模擬器能夠很好地模擬真實情況下的內(nèi)存分配,但如果可能的話,我們建議你在256 MB的設(shè)備上測試一下。
Tip #2——使用Windows Phone Memory profiler
Windows Phone SDK 7.1包括Windows Phone Memory Profiler。該工具使得你能夠看見當前內(nèi)存的分配圖,分析特定時間段內(nèi)內(nèi)存的使用情況,看到可行性的建議和一系列的托管堆。所有的Visual Studio版本上都有Memory Profiler。 閱讀Techniques for memory analysis of Windows Phone apps一文來了解揭示應用內(nèi)存使用情況的更多信息。
Tip #3——創(chuàng)建一個helper類來檢測應用程序是否安裝在256 MB的手機上
Windows Phone 7.5包括獲取手機上運行的應用的最大可用工作集的屬性。如果最大值小于90 MB(甚至是94371840字節(jié))則該應用應當被當成256 MB的手機。我們建議你創(chuàng)建一個通用的屬性幫助你為低內(nèi)存手機寫if-then-else 條件,如下所示:
public static class LowMemoryHelper{
public static bool IsLowMemDevice { get; set; }
?
static LowMemoryHelper()
{
try
{
Int64 result = (Int64)DeviceExtendedProperties.GetValue("ApplicationWorkingSetLimit");
if (result < 94371840L)
IsLowMemDevice = true;
else
IsLowMemDevice = false;
}
catch (ArgumentOutOfRangeException)
{
// Windows Phone OS update not installed, which indicates a 512-MB device.
IsLowMemDevice = false;
}
}
}
例如我們可以這么寫:
private void Application_Launching(object sender, LaunchingEventArgs e){
if (!LowMemoryHelper.IsLowMemDevice)
Allocate80MbOfMemory();
else
DontAllocate80MbOfMemory();
}
目的是為256 MB手機使用if-then-elses ,但有時是不可避免的。
Tip #4——不支持PeriodicTask 和 ResourceIntensiveTasks
256 MB 手機不支持PeriodicTask 和 ResourceIntensiveTask 類,如果試圖使用將throw 一個異常。這兩個類是開發(fā)者在特定的限制下將代碼作為后臺進程執(zhí)行。很容易明白為什么不支持這些類。ResourceIntensiveTask 可以沒有上限地運行任何代碼。想象你有一個256 MB的設(shè)備,操作系統(tǒng)使用大概100 MB,一個應用使用60 MB的工作集另一個后臺進程使用另外60 MB的工作集。這很有可能導致手機崩潰。激活另一個后臺進程(例如,需要15 MB的背景音樂)將導致整個手機內(nèi)存不足。
100MB + 60MB + 60MB + 15MB ≈ 256MB
類似的計算解釋了為什么PeriodicTask不能被使用。使用10個后臺代理,每個需要6 MB的內(nèi)存,10 PeriodicTasks 就相當于另一個應用程序使用60 MB的內(nèi)存。關(guān)于PeriodicTask 和 ResourceIntensiveTask 的更多信息請參考Background Agents Overview for Windows Phone。要特別注意后臺聲音的BackgroundTasks 和后臺文件傳輸和Scheduled Alarms 及 Reminders將繼續(xù)在256 MB的手機上運行。
Tip: 應用程序仍然可以包含PeriodicTask 和 ResourceIntensiveTask的代碼。當你試圖運行它們時候?qū)伋霎惓!?/p>
推薦的最佳做法是總是在代碼里使用if-then-else (#3里所提到的)而不要在256 MB手機里對PeriodicTask 或 ResourceIntensiveTasks 進行初始化,如下所示:
private void Application_Launching(object sender, LaunchingEventArgs e){
if (!LowMemoryHelper.IsLowMemDevice)
InitializePeriodicTaskToUpdateLiveTiles();
else
InitializePushNotificationsToUpdateLiveTiles();
}
有一些使用情況可以使用其他手段來彌補失去的特性。例如PeriodicTask 支持的Live Tiles能被Push Notification支持的Live Tiles所代替。
在Windows Phone 7.5 中后臺代理只是想為程序提供額外的功能而不是核心功能,用戶可以關(guān)閉這些功能。然而,如果你的應用圍繞PeriodicTask 或 ResourceIntensiveTask 最好讓它不支持256 MB的應用程序。
Tip #5——使用WebBrowserTask代替<WebBrowser />控件來顯示任意未測試的網(wǎng)頁
在Windows Phone 7里,可以使用Internet Explorer <WebBrowser /> 控件將任何URL的頁面裝載到應用程序上。然而,一些網(wǎng)頁可能會導致過度的內(nèi)存消耗。尤其是那些不是為手機網(wǎng)頁瀏覽器量身定做的網(wǎng)站更可能引起手機上嚴重的內(nèi)存消耗。
例如, <WebBrowser /> 指向包括代碼的不是為手機瀏覽器定義的網(wǎng)頁,例如
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"><phone:WebBrowser Source="http://www.yvettesbridalformal.com"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" />
</Grid>
將引起大量的內(nèi)存使用。
注意不是所有的網(wǎng)站將在256 MB手機上引起問題。例如,對一個更加現(xiàn)代化的網(wǎng)站來說,內(nèi)存消耗將在一個可接受的范圍內(nèi),如下所示:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"><phone:WebBrowser Source="http://developer.nokia.com"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" />
</Grid>
甚至當導航到測試過的網(wǎng)站,確保它們只導航到先前的測試過的頁面這一點很重要。一個選擇是阻止導航到已知的使用過多內(nèi)存的網(wǎng)站。一般情況下最好限制導航到已經(jīng)成功測試過的已知網(wǎng)站而不限制到特定的網(wǎng)站。
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"><phone:WebBrowser Source="http://developer.nokia.com"
Navigating="WebBrowser_Navigating"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" />
</Grid> private void WebBrowser_Navigating(object sender, NavigatingEventArgs e)
{
if (e.Uri.OriginalString == "http://www.yvettesbridalformal.com")
{
e.Cancel = true;
}
}
為了保證你的應用程序在256 MB手機上<WebBrowser /> 控件不會帶來內(nèi)存問題,簡單的方法是一直使用WebBrowserTask。WebBrowserTask將打開一個單獨的應用程序并且當內(nèi)存緊張的時候墓碑化應用程序。因此確保你的應用程序支持墓碑機制。
private void Button_Click(object sender, RoutedEventArgs e){
new WebBrowserTask()
{
Uri = new Uri("http://developer.nokia.com", UriKind.Absolute)
}.Show();
}
為<WebBrowser /> 控件推薦的最佳做法是將<WebBrowser />中的所有可能導致內(nèi)存問題的所有頁面在內(nèi)存分析器下運行。請確保任何時刻的內(nèi)存消耗不超過90 MB。如果你不能限制應用程序中的外部鏈接(Reddit類似的應用程序),不要使用<WebBrowser /> 控件,而是使用WebBrowserTask。另一個可能性是一種混合的方法監(jiān)測<WebBrowser /> 的內(nèi)存使用,如果它超過90 MB然后你將控件從visual tree中移除并啟動WebBrowserTask。
Tip #6——使用BingMapsTask代替Bing <Map />控件
Bing <Map /> 控件用來加載地圖。Maps是由很多小的點陣圖組成的,它取決于地圖的緯度和經(jīng)度的位置、放大系數(shù)和其它的少數(shù)因素。那是許多潛在的位圖。每次用戶與Bing <Map /> 控件相互作用的時候新的位圖將被從必應地圖服務(wù)器上下載下來并載入到內(nèi)存中。甚至一個小的Maps控件也能加載很多的圖片。
<m:Mapxmlns:m="clr-namespace:Microsoft.Phone.Controls.Maps;assembly=Microsoft.Phone.Controls.Maps"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
當導航到該地圖兩分鐘后你將看到內(nèi)存幾乎是50 MB,很多圖片被初始化并且產(chǎn)生5個不同的垃圾收集器。對于512 MB 上90 MB的工作集的手機來說50 MB比256 MB設(shè)備上的60 MB工作集的問題小得多。因此需要更加注意256 MB手機上的Bing <Map /> 控件。 一個可能的很快的但不太好的修復方法是使得必應地圖控件成為非交互性的。
<m:Mapxmlns:m="clr-namespace:Microsoft.Phone.Controls.Maps;assembly=Microsoft.Phone.Controls.Maps"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
IsHitTestVisible="False" />
通過設(shè)置IsHitTestVisible=False 可以本質(zhì)上說Bing Maps控件是靜態(tài)的。通過在Bing <Maps /> 控件里禁止用戶的導航,你可以基本上避免這個控件帶來的大量圖片的加載。將要加載的圖片只是來自于你所設(shè)置的最初的屬性。
然而,如果你需要允許用戶在map里導航,上面那種就用不了了。在這種情況下建議你使用BingMapsTask。BingMapsTask將打開一個單獨的應用程序并且當內(nèi)存緊張的時候墓碑化應用程序。因此請確保你的應用程序支持墓碑機制。
private void Button_Click(object sender, RoutedEventArgs e){
new BingMapsTask()
{
SearchTerm = "Espoo, Finland"
}.Show();
}
推薦最好的做法是使用BingMapsTask代替Bing <Map /> 控件。另外一個可能性是一種混合的方法監(jiān)測Bing <Map/> 的內(nèi)存使用情況,如果它超過90 MB然后你將控件從visual tree中移除并啟動BingMapsTask。
Tip #7——考慮降低圖片的質(zhì)量
圖片至少消耗其在硬盤所占大小的那么多的內(nèi)存。非移動的優(yōu)化的圖片的過度使用將不可避免地導致非常大的內(nèi)存使用量。減少圖片內(nèi)存痕跡有很多方法:使用480x800圖片最大尺寸,廣泛地選擇圖片格式(PNG或JPG)并減少所需要圖片的質(zhì)量。 例如,這個URL有一張4913x3400的圖片
[File:Windows Phone image memory large.png]
你可以看到右上方的<MemoryCounter /> 顯示了該圖片占用了13MB-16MB的內(nèi)存,而不是默認Windows Phone 7應用程序所占用的6 MB的內(nèi)存。分配了8 MB的內(nèi)存。你可以在Windows Phone上縮減該圖片的最大分辨率,這樣將節(jié)省大量內(nèi)存。
讓我們將圖片的寬度縮成800像素,這也差不多是WP7上所需要的任何圖片的最大寬度。通過限制圖片的最大分別率我們不會失去高質(zhì)量性也不會影響用戶體驗但降低了內(nèi)存占用量。
[File:Windows Phone image memory small.png]
我們可以看到僅僅通過將該圖片的大小從4913x3400 重新設(shè)置為 800x554就將其內(nèi)存占用量從13-17MB 降低到 9-13MB。為<Image /> 控件推薦的最佳做法是只要有可能就選擇低分辨率的圖片。如果在你的實際情況中低分辨率的圖片不可用,與其在服務(wù)器上調(diào)整圖片的大小不如不顯示該圖片。
Tip #8——考慮用使用數(shù)據(jù)虛擬化的ListBox代替一長串的圖片
正如我們剛剛所看到的圖片有可能占用大量的內(nèi)存。但是因為一個圖片就占用了不小的內(nèi)存那一連串的圖片占用的內(nèi)存將相當?shù)亩?。讓我們看一個使用一連串的Flickr圖片的例子。
作為第一步,我們要下載Flickr.net API并向FlickrNetWP7 集合添加一個引用。接下來我們搜索Flickr并將他們添加到UI:
private void MainPage_Loaded(object sender, RoutedEventArgs e){
Flickr flickr = new Flickr("<flickr API token>", "<flickr API secret>");
flickr.PhotosSearchAsync(new PhotoSearchOptions(null, "nokia"),
result =>
{
Dispatcher.BeginInvoke(() =>
lst.ItemsSource = result.Result);
});
}
連同它們相應的標題列出這些圖片:
<ListBox x:Name="lst" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"><ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding LargeUrl}" Width="200" Stretch="UniformToFill"/>
<TextBlock Text="{Binding Title}" Margin="2" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
運行該應用程序并對其進行內(nèi)存分析你將看到內(nèi)存超過了90 MB。隨著各個圖片被初始化,你甚至可以看到內(nèi)存使用量上的小“臺階”。
一種解決方法是限制所顯示圖片的總數(shù)量為10然后放到一個單獨的頁面上。另一個方法是從使用大的Flickr圖片轉(zhuǎn)向使用更小的Flickr。在該例中我們限制一次只顯示10個小的Flickr圖片。
<ListBox x:Name="lst" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"><ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding SmallUrl}" Width="200" Stretch="UniformToFill"/>
<TextBlock Text="{Binding Title}" Margin="2" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox> private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
Flickr flickr = new Flickr("2191ef82aa075c112349ff21c45f4b27", "224975f561e65fc4");
flickr.PhotosSearchAsync(new PhotoSearchOptions(null, "amazing everyday"),
result =>
{
Dispatcher.BeginInvoke(() =>
lst.ItemsSource = result.Result.Take(10));
});
}
當我們?yōu)樵搼贸绦蜻\行內(nèi)存分析器時我們可以看到一個更合理的內(nèi)存消耗量。
我們使用非常少的功能變化改變了該應用程序的內(nèi)存占用量。當然,針對每個應用程序你需要衡量長列表的圖片是不是有意義。推薦給開發(fā)人員的最佳做法是查閱任何長列表的圖片,分析那些頁面的內(nèi)存占用情況并根據(jù)需要改變用戶體驗。第一步是分析用使用了數(shù)據(jù)虛擬化的ListBox代替后的內(nèi)存占用,例如Peter Torr's LazyListBox或David Anson's DeferredLoadListBox。如果只是改變ListBox控件變體不起作用,你就需要考慮用戶體驗的變換了。例如假設(shè)使用分頁,將不同類別的數(shù)據(jù)放在不同的頁面上或使用Silverlight Toolkit LongListSelector。用戶體驗的變化取決于特定的商業(yè)域和用戶體驗要求。
Tip #9——考慮禁止頁面轉(zhuǎn)換
頁面轉(zhuǎn)換是用戶在不同的頁面之間進行導航的動畫(例如flip-in 和 flip-out)。在WP7上那些動畫一般都是通過使用TransitionFrame 和 TransitionService的Silverlight Toolkit for Windows Phone來完成的。在這個部分我們將致力于使用TransitionFrame 和 TransitionService對內(nèi)存消耗的影響。我們將看到頁面轉(zhuǎn)換的內(nèi)存消耗量大約是5 MB。與90 MB的工作集相比,5 MB對60 MB的工作集來說也是挺重要的。任何或所有的頁面轉(zhuǎn)換將引起該內(nèi)存占用而不僅僅是Silverlight Toolkit的實現(xiàn)。同時有兩個頁面產(chǎn)生動畫的實現(xiàn)將內(nèi)在地消耗不少的內(nèi)存。
我們從下載Silverlight Toolkit for Windows Phone開始我們的例子。你可以使用NuGet安裝Silverlight Toolkit或安裝MSI并添加Microsoft.Phone.Controls.Toolkit 引用。一旦你完成這些你將需要對你的程序做兩點改變。第一是在App.xaml.cs里使用TransitionFrame而不使用老式的PhoneApplicationFrame。
//RootFrame = new PhoneApplicationFrame();RootFrame = new TransitionFrame();
對于每個頁面我們想要啟用頁面轉(zhuǎn)換因為我們將要添加下面的XAML代碼來指定動畫發(fā)生的位置。若要了解怎樣使用TransitionFrame 的更多信息請關(guān)注WindowsPhoneGeek的Windows Phone 7 Navigation Transitions Step By Step指導。
<toolkit:TransitionService.NavigationInTransition><toolkit:NavigationInTransition>
<toolkit:NavigationInTransition.Backward>
<toolkit:TurnstileTransition Mode="BackwardIn"/>
</toolkit:NavigationInTransition.Backward>
<toolkit:NavigationInTransition.Forward>
<toolkit:TurnstileTransition Mode="ForwardIn"/>
</toolkit:NavigationInTransition.Forward>
</toolkit:NavigationInTransition>
</toolkit:TransitionService.NavigationInTransition>
<toolkit:TransitionService.NavigationOutTransition>
<toolkit:NavigationOutTransition>
<toolkit:NavigationOutTransition.Backward>
<toolkit:TurnstileTransition Mode="BackwardOut"/>
</toolkit:NavigationOutTransition.Backward>
<toolkit:NavigationOutTransition.Forward>
<toolkit:TurnstileTransition Mode="ForwardOut"/>
</toolkit:NavigationOutTransition.Forward>
</toolkit:NavigationOutTransition>
</toolkit:TransitionService.NavigationOutTransition>
當運行該應用程序時我們發(fā)現(xiàn)當前內(nèi)存占用量約為12 MB最高占用量約為17 MB。
如果我們禁止頁面轉(zhuǎn)換我們可以發(fā)現(xiàn)當前內(nèi)存使用量將有所降低,但變化最明顯的是最高內(nèi)存使用量。我們可以通過原先的PageTransitionFrame 而不是使用TransitionFrame來禁止頁面轉(zhuǎn)換。
RootFrame = new PhoneApplicationFrame();//RootFrame = new TransitionFrame();
當我們禁止頁面轉(zhuǎn)換后再運行該應用程序我們發(fā)現(xiàn)內(nèi)存占用量或多或少的降低了。
在下圖中我們可以清晰地看見簡化了的應用的實驗結(jié)果:
?
當頁面轉(zhuǎn)換能實現(xiàn)Metro UI "fast and fluid"的原理,即使我們只有60 MB的可用內(nèi)存的時候損失5MB-7MB的內(nèi)存也不為過。這是一個微妙的平衡。對大多數(shù)應用程序來說對256 MB設(shè)備禁用頁面轉(zhuǎn)換起作用,除非你能保證整個應用程序的內(nèi)存使用量不超過55MB~。
if (LowMemoryHelper.IsLowMemDevice){
RootFrame = new PhoneApplicationFrame();
}
else
{
RootFrame = new TransitionFrame();
}
推薦開發(fā)人員的最佳做法是在256 MB的設(shè)備上禁用頁面轉(zhuǎn)換,除非在256 MB的設(shè)備上測試過他
們的應用程序并且整個內(nèi)存使用量不超過90 MB。
Tip #10——避免多次初始化同一個SoundEffects
很多XNA游戲甚至是少數(shù)Silverlight應用程序使用SoundEffect 來播放簡短的音頻。最常見的是在游戲里添加聲音效果。這種效果可以帶來槍聲、移動、碰撞和擊打的效果。那些事件頻繁發(fā)生在游戲中。然而,初始化多個SoundEffects 但不處置它們將引起不少的臨時內(nèi)存。若要了解關(guān)于在WP7 中使用SoundEffect 的更多信息請關(guān)注Maarten Struys的Adding Sound Effects to a Windows Phone 7 Silverlight Application。
256 MB設(shè)備一個糟糕的做法是每次播放聲音都初始化一個SoundEffect 。
private void Button_Click(object sender, RoutedEventArgs e){
SoundEffect beep = SoundEffect.FromStream(
Application.GetResourceStream(
new Uri("NokiaBeep.wav", UriKind.RelativeOrAbsolute))
.Stream);
?
FrameworkDispatcher.Update();
beep.Play();
}
如果我們運行該應用程序并多次短而快速連續(xù)地點擊按鈕,其內(nèi)存使用情況如下所示:
你將會看到即使SoundEffects 不能被重復使用或配置,SoundEfffect將觸發(fā)Garbage Collector運行GC事件。這種情況是可以被512 MB的設(shè)備所接受的。但是由于逐漸累積的內(nèi)存在垃圾回收之前就能輕易地超過60 MB,這對256 MB的設(shè)備來說是不好的。在我們的一個簡單的例子中我們幾乎沒有visuals和確切的游戲邏輯能夠達到40MB~的內(nèi)存使用量。當你的工作集僅僅只有60 MB的時候,不處置或再利用SoundEffects 內(nèi)存的使用量越來越明顯。
XNA開發(fā)社區(qū)提供了很多種好的方法處理SoundEffects。你可以使用timer全體地處理soundeffects;你可以將可重復利用的SoundEffects保存在字典中,等等。在我們的例子中將SoundEffect 保存了起來當頁面不再可見并不再被需要的時候處理掉它。
private SoundEffect beep = null;private void Button_Click(object sender, RoutedEventArgs e)
{
if (beep == null)
{
beep = SoundEffect.FromStream(
Application.GetResourceStream(
new Uri("NokiaBeep.wav", UriKind.RelativeOrAbsolute))
.Stream);
}
?
FrameworkDispatcher.Update();
beep.Play();
}
?
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
beep.Dispose();
}
通過做出這個小的改變我們只分配了一個SoundEffect,該應用的行為是相同的并且我們已經(jīng)很大地減少了內(nèi)存使用量。在內(nèi)存中我們不再分配很多SoundEffects 而是只分配了一個。推薦的最佳做法是避免多次初始化同一個SoundEffects ,當需要時保存初始化過的SoundEffects 不需要時處理掉它們。
Tip #11——壓縮XNA assets
XNA游戲能夠?qū)⒎浅6嗟腶ssets加載到內(nèi)存中所以很容易超過90 MB。它將通過壓縮使用的vector data 或 textures減少一個元素整體的內(nèi)存使用量。最樂觀的情形下你可以在不影響質(zhì)量和不影響CPU和GPU表現(xiàn)的同時減少assets在硬盤上的大小和在內(nèi)存中的大小。在大多數(shù)情況下數(shù)據(jù)壓縮很有可能引起XNA assets質(zhì)量下降的問題。
針對你的XNA應用程序所擁有的assets壓縮有幾個選擇。例如,通過放棄位置的精確信息(通過normalizing vector data)節(jié)省模型的25%(每32字節(jié)節(jié)省8字節(jié))。另一個可能是使用DXT compression algorithms降低整個asset的質(zhì)量。這里的想法并不是“壓縮”在內(nèi)存中的內(nèi)容而沒有消耗顯著的CPU 或 GPU時間。這不是為了減少在硬盤上的大小而是減少在內(nèi)存中的大小。例如JPG壓縮對我們不起作用因為它只是壓縮在硬盤上的大小;然而DXT既能壓縮硬盤的占用量還能壓縮內(nèi)存的占用量。
這所有的壓縮算法將作為一個簡易包裝的步驟在開發(fā)機器上運行。此外當它依賴算法運行的時候壓縮算法將被應用程序所使用。若要了解XNA asset 壓縮的介紹信息,請參考Shawn Hargreaves的Compressed GPU data formats。
XNA游戲的最后一點是根據(jù)游戲的循環(huán)和當前的內(nèi)存消耗量計劃調(diào)用垃圾收集器(GC.Collect)。推薦XNA開發(fā)人員的最佳做法是分析它們內(nèi)存的使用量,如果需要的話(超過90 MB)探究asset壓縮策略。關(guān)于XNA內(nèi)存優(yōu)化的詳細消息請參考Improving Memory Use in XNA Games。
Tip #12——小心查找和排除內(nèi)存泄露
內(nèi)存泄露是由當正常使用應用程序突然出乎意料地、逐步地分配內(nèi)存但之后不再重新分配那部分內(nèi)存所引起的。內(nèi)存泄露的常見跡象是隨著每次頁面導航都減少了幾MB的內(nèi)存并且在重啟應用之前那些內(nèi)存無法回收利用。256 MB上內(nèi)存泄露情況與512 MB設(shè)備上內(nèi)存泄露情況一樣頻繁并且沒有什么區(qū)別。然而由于低內(nèi)存工作集(60 MB 超過 90 MB)的情況尤為明顯。例如在50 MB內(nèi)存上運行的WP7 應用程序可以在512 MB的設(shè)備上泄露40 MB,但在256 MB設(shè)備上只能泄露10 MB的工作集。在用戶明顯感到內(nèi)存泄露之前對應用程序的使用時間是相當少的。
若要了解關(guān)于怎樣診斷WP7上的內(nèi)存泄露請參考Windows Phone的博客Memory Profiling for Application Performance。
推薦的最佳做法是了解怎樣Find Managed Memory Leaks in WPF and Silverlight applications,在長時間的使用過程中分析應用程序并根據(jù)整個應用的性能監(jiān)聽用戶。如果用戶反映"隨著時間的推移應用逐漸的變得很‘累’ "或“當使用應用一個小時后應用總是崩潰”,那些就是內(nèi)存泄露的常見標志。在特定時間內(nèi)看看管理堆上有些什么并判斷它是不是應該在那兒。
?
轉(zhuǎn)載于:https://www.cnblogs.com/Yukang1989/archive/2012/12/21/2828320.html
總結(jié)
以上是生活随笔為你收集整理的向256 MB内存的Windows Phone提供应用的最佳实践指导的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 个人易遗忘的代码记录(6) 汉字转拼音
- 下一篇: 用xml配置文件加载资源时(XML和XM