dbvisualizer設置最大內存,Visual Studio的.NET內存分配分析器解析

 2023-12-06 阅读 17 评论 0

摘要:? Visual Studio 2012擁有豐富的有價值的功能,以至于我聽到開發者反饋的需要的新功能新版本已經有了。另外,我聽到開發人員詢問具體的功能的某個特性,實際上他真正需要的是另外一個功能點。 上面說的兩種情況下適用于Visual Studio的.NET內存分配分析器

?

Visual Studio 2012擁有豐富的有價值的功能,以至于我聽到開發者反饋的需要的新功能新版本已經有了。另外,我聽到開發人員詢問具體的功能的某個特性,實際上他真正需要的是另外一個功能點。

上面說的兩種情況下適用于Visual Studio的.NET內存分配分析器 。 許多開發人員可能會從中受益卻不知道它的存在,而另外一些開發者有卻對它有不正確的理解。 這樣很不好,因為該功能可以提供很多有價值的特定場景; 許多開發在理解的情況下才能發揮其預期的作用。也就是要做到以下兩點:第一,知道它的存在,第二,知道如何使用。

為什么內存分析?

dbvisualizer設置最大內存、當談到.NET和內存分析,有兩個主要的原因之一,可能需要使用一個診斷工具:

1. 發現內存泄漏。

2. 發現不必要的分配。

內存優化的實例

為了更好地理解內存分析器的作用,以及它如何幫助到我們。讓我們通過一個示例來理解。

? public static async Task<T> WithCancellation1<T>( this Task<T> task, CancellationToken cancellationToken)
 {
???? var tcs = new TaskCompletionSource< bool >();
???? using (cancellationToken.Register(() => tcs.TrySetResult( true )))
???? if (task != await Task.WhenAny(task, tcs.Task))
???????? throw new OperationCanceledException(cancellationToken);
???? return await task;
 }
上面這段代碼的作用是可以異步的取消正在運行的任務
?
? T result = await someTask; 
? T result = await someTask.WithCancellation1(token); 

java內存分析工具?如果取消要求在任務完成之前,相關的CancellationToken,一個OperationCanceledException將被拋出。

要了解參與這一方法的分配,我們將使用一個小程序去測試。
 
using System;
 using System.Threading;
 using System.Threading.Tasks;
 
 class Harness
 {
???? static void Main() 
????? { 
????????? Console.ReadLine(); // wait until profiler attaches
????????? TestAsync().Wait(); 
????? }
???? static async Task TestAsync()
???? {
???????? var token = CancellationToken.None;
???????? for ( int i=0; i<100000; i++)
???????????? await Task.FromResult(42).WithCancellation1(token);
???? }
 }
 
?
 static class Extensions
 {
???? public static async Task<T> WithCancellation1<T>(
???? this Task<T> task, CancellationToken cancellationToken)
???? {
???????? var tcs = new TaskCompletionSource< bool >();
???????? using (cancellationToken.Register(() => tcs.TrySetResult( true )))
???????????? if (task != await Task.WhenAny(task, tcs.Task))
???????????????? throw new OperationCanceledException(cancellationToken);
???????? return await task;
???? }
 } 

運行.NET內存分配分析器

要啟動內存分配分析器,在Visual Studio中去分析菜單并選擇“啟動性能向導...”。 這將打開如下所示的對話框:

clip_image002

選擇“.NET內存分配(取樣)”,單擊下一步兩次,最后是完成。 在這一點上,應用程序將被啟動,并剖析將開始監視它的分配(線束上面的代碼也需要你按下“Enter”鍵) 。 當應用程序完成后,或當你手動選擇停止剖析,剖析會加載符號,并開始分析跟蹤。 這是一個很好的時間去讓自己的一杯咖啡,或午??餐,因為這取決于有多少分配發生后,該工具可以需要一段時間才能做到這一點的分析。

vs2010調試查看內存。當分析完成后,我們看下報告:

clip_image004

從這里,我們可以進一步研究,通過查看分配匯總(從“當前視圖”下拉列表中選擇“分配”):

clip_image006

在這里,我們能看到一排的被分配的每種類型,同列顯示有多少分配被跟蹤的信息,有多少空間與分配,以及如何分配映射回該類型的百分比有關。 我們還可以擴展一個條目看,看到這些分配方法的調用堆棧:

C++內存泄漏的原因及解決辦法?clip_image008

通過選擇“功能”的觀點,我們可以得到一個不同的支點這一數據,高亮它的功能分配的大多數對象和字節:

clip_image010

剖析分析報告并做相應優化

我們可以分析我們的例子中的結果。 首先,我們可以看到,有相當數量的分配在哪里,這可能是令人驚訝的。畢竟,在我們的例子中我們使用WithCancellation1與已經完成了任務,這意味著應該有很少的工作要做(與已完成的任務,沒有什么取消).然而從上面的跟蹤我們可以看到,我們的例子中的每一次迭代中產生:

  • 三種分配Task`1的(我們跑了線束10萬次,可以看到有?300K分配)
  • 兩個分配task[]

visual studio內存多大。有關任務的輔助業務,它實際上是相當普遍的處理已經完成的任務,因為很多時候,操作執行是異步的,實際上完全同步(例如,在網絡流中的一個讀操作可以緩沖到內存足夠的額外數據來完成后續的讀操作)。 因此,優化已經完成的情況下,可以為表現的確有益。 讓我們來試試。 這里有一個第二次嘗試WithCancellation,一個優化的幾個“已完成”的情況:

?? public static Task<T> WithCancellation2<T>( this Task<T> task, 
?? CancellationToken cancellationToken)
???? {
???????? if (task.IsCompleted || !cancellationToken.CanBeCanceled)
???????????? return task;
???????? else if (cancellationToken.IsCancellationRequested)
???????????? return new Task<T>(() => default (T), cancellationToken);
???????? else
???????????? return task.WithCancellation1(cancellationToken);
???? } 

此實現檢查:

  • 首先,無論是任務已經完成或是否提供的CancellationToken無法取消; 在兩者的那些情況下,有不需要額外的工作,因為取消不能適用,因此我們可以只返回原始任務立即而不是花費任何時間或存儲器中創建一個新的。
  • 那么是否取消已要求; 如果有,我們可以分配一個業已取消的任務將返回,而不是花費八個分配我們先前支付給調用我們原來的實現。
  • 最后,如??果沒有這些快速通道申請,我們通過降至調用原始的實現。

再分析我們的微基準,而使用的,而不是WithCancellation1 WithCancellation2提供了大大改善的前景(你很可能會發現,分析的速度遠遠超過它之前,已經是一個跡象,表明我們已經顯著減少內存分配完成)。 現在,我們剛剛有主要業務劃分,我們預計,從Task.FromResult一個從線束我們TestAsync方法叫做:

clip_image012

所以,我們現在已經成功了優化,其中任務已經完成,取消在那里不能要求,或者取消已申請的情況。 怎么樣的情況下,我們確實需要調用更復雜的邏輯? 是否有可有什么改進?

c++內存管理?讓我們改變我們的基準來使用,這不是已經由我們引用WithCancellation2,并且還使用可以有取消請求令牌的時間內完成的任務。 這將確保我們使它的“慢”的路徑:

?????? using (cancellationToken.Register(() => tcs.TrySetResult( true ))) 

剖析再次提供了更深入的了解:

clip_image014

在這種緩慢的道路,現在有14%的迭代撥款總額,包括2從我們TestAsync線束(該TaskCompletionSource <int>的我們明確地創建和任務<int>的它創建)。 在這一點上,我們可以使用所有的分析結果提供的信息,了解那里的其余12分配的來源,并隨后解決這些問題的是相關的和可能的。 例如,讓我們看兩個分配具體為:在<> c__DisplayClass2`1實例,這兩個動作實例之一。 這兩種分配將可能是合乎邏輯的任何人都熟悉的C#編譯器如何處理倒閉 。 為什么我們有一個封閉? 由于該行的:

使用(cancellationToken.Register(()=> tcs.TrySetResult( 真 )))

電話注冊,是關在'TCS'變量。 但是,這不是嚴格必需的:該注冊方法具有另一個超載,而不是采取一個動作這需要一個Action <object>和該對象的狀態被傳遞給它。 如果我們不是重寫此行使用基于狀態的過載,以及一個手動緩存的委托,我們能夠避免倒閉和這兩個分配:

? private static readonly Action< object > s_cancellationRegistration =
???? s => ((TaskCompletionSource< bool >)s).TrySetResult( true );
 using (cancellationToken.Register(s_cancellationRegistration, tcs))

重新運行探查證實這兩個分配不再發生:

從今天開始分析!

分析,發現和消除熱點,然后將再次圍繞這個周期是改善代碼的性能,常見的方法是否使用CPU分析器和內存分析器。 所以,如果你發現內存分配有可能程序的瓶頸,不妨嘗試.NET的內存分配分析器。

轉載于:https://www.cnblogs.com/sennly/p/4179418.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/4/192835.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息