{"id":2053,"date":"2013-12-20T12:44:00","date_gmt":"2013-12-20T12:44:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/visualstudioalm\/2013\/12\/20\/investigating-memory-leaks-in-azure-web-sites-with-visual-studio-2013\/"},"modified":"2022-07-18T06:14:30","modified_gmt":"2022-07-18T14:14:30","slug":"investigating-memory-leaks-in-azure-web-sites-with-visual-studio-2013","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/devops\/investigating-memory-leaks-in-azure-web-sites-with-visual-studio-2013\/","title":{"rendered":"Investigating Memory Leaks in Azure Web Sites with Visual Studio 2013"},"content":{"rendered":"<p>One of the cool new features in Visual Studio 2013 is the <a href=\"http:\/\/blogs.msdn.com\/b\/visualstudioalm\/archive\/2013\/06\/20\/using-visual-studio-2013-to-diagnose-net-memory-issues-in-production.aspx\">ability to analyze managed memory issues<\/a>. Recently, Azure Web Sites added support to programmatically get <a href=\"http:\/\/weblogs.asp.net\/scottgu\/archive\/2013\/06\/27\/windows-azure-general-availability-release-of-web-sites-mobile-services-new-autoscale-alerts-support-no-credit-card-needed-for-msdn-subscribers.aspx\">mini-dumps and \u201cdiagsession\u201d files that have heap information from Azure Web Sites in production<\/a>. In this walkthrough, I\u2019ll show you how to combine these two new features to form a cool end to end scenario for investigating memory leaks in production Azure Web Sites using a little PowerShell.<\/p>\n<h2>Set up an Azure Web Site using Git<\/h2>\n<p>I\u2019m going to start from scratch with setting up a new website using git deployment. The key takeaways from this first section is that you need to know the deployment credentials because those will be the same credentials we use to grab a heap dump of the website\u2019s process.<\/p>\n<p>First, let\u2019s install git. I think the easiest way to do this is to use chocolatey, a great package manager built on nuget. Run the following command from an elevated command prompt (not PowerShell) to get chocolatey on your machine:<\/p>\n<pre>@powershell -NoProfile -ExecutionPolicy unrestricted -Command <\/pre>\n<pre>\"iex ((new-object net.webclient).DownloadString('https:\/\/chocolatey.org\/install.ps1'))\" <\/pre>\n<pre>&& SET PATH=%PATH%;%systemdrive%chocolateybin<\/pre>\n<p>Now that we have chocolatey, we can quickly install the git package.<\/p>\n<pre>cinst git<\/pre>\n<p>Start VS2013 and create a new MVC 4 application. Accept the defaults and build. It doesn\u2019t really matter what site you use here as long as you know it works. Now it is time to deploy it to an Azure Web Site with git. In an elevated powershell, change to the folder that contains the app:<\/p>\n<pre>Cd C:usersYOURUSERIDdocumentsvisual studio 2013projectsMyApp<\/pre>\n<p>Create a new local repo and add and commit the web site you want to deploy to it:<\/p>\n<pre>git init\ngit add .\ngit commit \u2013m \u201cinitial commit\u201d<\/pre>\n<p>Open a browser and navigate to the Azure management portal. Create a new Azure Web Site:<\/p>\n<p><img decoding=\"async\" border=\"0\" alt=\"\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2013\/12\/1007.1.png\" \/><\/p>\n<p>Once the site has been created, it is time to set up the deployment credentials so you can actually publish your site. From the dashboard, select \u201cSet up deployment credentials\u201d.<\/p>\n<p><img decoding=\"async\" border=\"0\" alt=\"\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2013\/12\/1513.2.png\" \/><\/p>\n<p>It will ask you for a user name and password combination for Git deployments. Note it down. This will be the same credentials that are used to access minidumps and other diagnostic information in later steps.<\/p>\n<p><img decoding=\"async\" border=\"0\" alt=\"\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2013\/12\/7331.3.png\" \/><\/p>\n<p>Go back to the Dashboard and select \u201cSet up deployment from source control.\u201d Choose Local Git repository. Azure will create a repo for you to target.<\/p>\n<p><img decoding=\"async\" border=\"0\" alt=\"\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2013\/12\/6786.4.png\" \/><\/p>\n<p>Move back to PowerShell and follow the instructions that you get from Azure.<\/p>\n<p><img decoding=\"async\" border=\"0\" alt=\"\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2013\/12\/8420.5.png\" \/><\/p>\n<p>Once you\u2019ve completed the deployment you should test to make sure you can hit your new web site. Make note of the prefix of the URI that your git publish is targeting. In my example, it is <a href=\"http:\/\/myminidumps.scm.azurewebsites.net\/\">http:\/\/myminidumps.scm.azurewebsites.net\/<\/a> . This is going to be the base URI for all the REST APIs you call.<\/p>\n<h2>Calling the Diagnostics REST APIs from PowerShell<\/h2>\n<p>Let\u2019s start by grabbing the diagnostic counters from the Diagnostics REST APIs. We\u2019ll do this with the Invoke-WebRequest PowerShell cmdlet. The API documentation is located here: <a href=\"https:\/\/github.com\/projectkudu\/kudu\/wiki\/Process-Threads-list-and-minidump-gcdump-diagsession\">https:\/\/github.com\/projectkudu\/kudu\/wiki\/Process-Threads-list-and-minidump-gcdump-diagsession<\/a>. The most basic call is to \/diagnostics\/processes which will return several important counters about the w3wp.exe process running your website. I take the returned content and format it nicely by piping to the ConvertFrom-Json cmdlet:<\/p>\n<pre>(Invoke-WebRequest \u2013uri <a href=\"https:\/\/mysite.scm.azurewebsites.net\/diagnostics\/processes\/0\">https:\/\/mysite.scm.azurewebsites.net\/diagnostics\/processes\/0<\/a> \u2013credential mycredential).Content | ConvertFrom-Json<\/pre>\n<p>It should look something like this:<\/p>\n<p><img decoding=\"async\" border=\"0\" alt=\"\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2013\/12\/4863.6.png\" \/><\/p>\n<p>Notice all the great memory counters which could point us to a leak. Knowing that you have a leak is a great first step but how would you investigate the cause? You actually have two options in the current version of Azure Web Sites: full heap dumps and managed gcdumps. Heaps dumps are complete snapshot of the state of the process at the time you issue the dump command via REST. GCDump files are compressed and don\u2019t have the ability to inspect the heap itself but has the complete reference graph which should be sufficient to track down most leaks. The major advantage of GCDump files is that they are small and should work well with the Free tier of Azure Web Sites. We\u2019ll use GCDumps for this walkthrough.<\/p>\n<h2>Getting the managed heap file<\/h2>\n<p>The URL for taking a GCDump of a process is \/diagnostics\/processes\/0\/gcdump. The outfile parameter to the powershell snippet below specifies where to write the dump. We are using the .diagsession extension so VS will know to open it as a managed memory file.<\/p>\n<pre>Invoke-WebRequest -uri <a href=\"https:\/\/&lt;Website&gt;.scm.azurewebsites.net\/diagnostics\/processes\/0\/gcdump\">https:\/\/&lt;Website&gt;.scm.azurewebsites.net\/diagnostics\/processes\/0\/gcdump<\/a> <\/pre>\n<pre>-credential &lt;InsertDeploymentUserIdFromAboveHere&gt; -outfile .dump.diagsession<\/pre>\n<p>Once you have the dump file, switch back to Visual Studio. Choose File->Open and your diagsession file location. You should now see something that looks like the screenshots below that lets you drill in to each type to see the size of each instance and in the pane below you can drill into the references that are keeping objects of that type alive.<\/p>\n<p><img decoding=\"async\" border=\"0\" alt=\"\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2013\/12\/6165.7.png\" \/><\/p>\n<p><img decoding=\"async\" border=\"0\" alt=\"\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2013\/12\/5584.8.png\" \/><\/p>\n<p>Hopefully this tutorial will get you started with finding memory leaks in your Azure Web Sites.<\/p>\n<p>To learn more about how to do memory analysis with these tools, check out Andrew\u2019s blog post <a href=\"http:\/\/blogs.msdn.com\/b\/visualstudioalm\/archive\/2013\/06\/20\/using-visual-studio-2013-to-diagnose-net-memory-issues-in-production.aspx\">here<\/a> for much more info.<\/p>\n<p>As always, we look forward to your feedback in the comments.<\/p>\n<p><strong>Update:<\/strong><\/p>\n<p>If you update to CTP 1 (or later) of the Spring Update of Visual Studio 2013, we\u2019ve added a small enhancement that makes this scenario much better.\u00a0\u00a0 The easiest way to identify a leak is usually to compare two diagsession files and see what has changed between them.\u00a0\u00a0 This helps you narrow in on the largest change directly instead of opening two files up and comparing them manually.\u00a0\u00a0 It\u2019s super simple.\u00a0\u00a0 Just make sure you follow the instructions above to get a diagsession file.\u00a0\u00a0 Allow the leak to accumulate for a while using the technique above for monitoring the size of the memory counters (private_memory or virtual_memory are good clues) then take another snapshot.\u00a0<\/p>\n<p>Open the later of the two files as before but now you can select \u201cCompare To->Browse\u2026\u201d in order to compare to the baseline you took.<\/p>\n<p><img decoding=\"async\" title=\"Select\" style=\"border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px\" border=\"0\" alt=\"Select\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2013\/12\/0081.Select_thumb_0D00DF19.png\" width=\"591\" height=\"310\" \/><\/p>\n<p>Now, you should see several new columns for the difference between the number and size of each type.\u00a0\u00a0 I usually sort on Size in bytes to try to identify which types are leaking.<\/p>\n<p><img decoding=\"async\" title=\"Diff\" style=\"border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px\" border=\"0\" alt=\"Diff\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2013\/12\/8322.Diff_thumb_4AFD0088.png\" width=\"852\" height=\"389\" \/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the cool new features in Visual Studio 2013 is the ability to analyze managed memory issues. Recently, Azure Web Sites added support to programmatically get mini-dumps and \u201cdiagsession\u201d files that have heap information from Azure Web Sites in production. In this walkthrough, I\u2019ll show you how to combine these two new features to [&hellip;]<\/p>\n","protected":false},"author":60,"featured_media":45953,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1,225],"tags":[],"class_list":["post-2053","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops","category-git"],"acf":[],"blog_post_summary":"<p>One of the cool new features in Visual Studio 2013 is the ability to analyze managed memory issues. Recently, Azure Web Sites added support to programmatically get mini-dumps and \u201cdiagsession\u201d files that have heap information from Azure Web Sites in production. In this walkthrough, I\u2019ll show you how to combine these two new features to [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/2053","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/users\/60"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/comments?post=2053"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/2053\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media\/45953"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media?parent=2053"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/categories?post=2053"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/tags?post=2053"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}