{"id":108789,"date":"2023-09-18T07:00:35","date_gmt":"2023-09-18T14:00:35","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=108789"},"modified":"2023-09-18T06:25:53","modified_gmt":"2023-09-18T13:25:53","slug":"when-looking-to-free-up-disk-space-dont-forget-your-symbol-file-caches","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20230918-35\/?p=108789","title":{"rendered":"When looking to free up disk space, don&#8217;t forget your symbol file caches"},"content":{"rendered":"<p>If you&#8217;re trying to free up disk space on a developer system, one place to look for unwanted files is your debugger symbol file caches.<\/p>\n<p>The Windows debugging engine creates a cache of symbol files so it can avoid downloading them repeatedly from the configured symbol server. And that cache can get kind of big, since there&#8217;s no automatic pruning.\u00b9 This is the disk space version of <a href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20060502-07\/?p=31333\"> A cache with a bad policy is another name for a memory leak<\/a>.<\/p>\n<p>Places to look are<\/p>\n<ul>\n<li><tt>$(DebuggerInstallDirectory)\\sym<\/tt><\/li>\n<li><tt>%TEMP%\\sym<\/tt><\/li>\n<li>Any directories that have ever been listed in <a href=\"https:\/\/docs.microsoft.com\/windows\/win32\/dxtecharts\/debugging-with-symbols\"> <tt>%_NT_SYMBOL_PATH%<\/tt><\/a>\u00b2<\/li>\n<li><tt>C:\\SymCache<\/tt><\/li>\n<li><tt>C:\\symbols<\/tt><\/li>\n<\/ul>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/devops\/understanding-symbol-files-and-visual-studios-symbol-settings\/\"> Visual Studio also caches symbols<\/a>. You can configure where it saves them under <i>Tools<\/i>, <i>Options<\/i>, <i>Debugging<\/i>, <i>Symbols<\/i>, <i>Cache symbols in this directory<\/i>. It defaults to <tt>%TEMP%\\SymbolCache<\/tt>.<\/p>\n<p>My tool of choice for investigating disk space is <a href=\"https:\/\/wiztreefree.com\/\">WizTree<\/a>. I have no stake in this program. Just a happy (paying) customer.<\/p>\n<p>What I do is create a symbolic link from each of these potential cache directories into a single directory <tt>C:\\SymCache<\/tt>, so that the different debuggers can share symbol caches.<\/p>\n<p><b>Bonus chatter<\/b>: Many years ago, I was working on a laptop and fired up the Disk Cleanup tool, and heard the laptop fan shriek to life as it was &#8220;calculating how much space you will be able to free&#8221;. This seemed odd, so I connected a debugger to figure out why merely deciding what to do was a CPU-intensive operation.\u00b3<\/p>\n<p>It turns out that the Disk Cleanup tool was in a tight loop checking whether the Cancel button had been clicked, while a background thread was busy doing the calculations. This behavior was part of the Disk Cleaner&#8217;s original implementation in Windows 98, which was particularly ironic since Windows 98 did not support multiprocessing, so the code was saturating your only CPU just to see if it should keep waiting, starving out the background thread that&#8217;s actually doing work.<\/p>\n<p>For Windows 10 Version 1709, I fixed it so the code didn&#8217;t poll the Cancel button. It just went into a normal message pump, and checked the state of the Cancel button after each message. Clicking the Cancel button would itself generate a message, so checking after each message was sufficient.<\/p>\n<p>This dropped the CPU usage of the UI thread down to basically zero.<\/p>\n<p><a title=\"What one Windows XP feature am I most proud of?\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20051201-09\/?p=33133\"> Previously, in CPU spin loops<\/a>.<\/p>\n<p><b>Bonus bonus chatter<\/b>: A few weeks after I fixed the problem, the Windows performance team filed a bug saying that their telemetry identified the Disk Cleanup tool&#8217;s Cancel dialog as consuming an unusually high amount of CPU. I had the satisfaction of telling them, &#8220;Already fixed.&#8221;<\/p>\n<p>\u00b9 You can perform manual pruning with the <a href=\"https:\/\/docs.microsoft.com\/windows-hardware\/drivers\/debugger\/using-agestore\"> AgeStore<\/a> program.<\/p>\n<p>\u00b2 You can tell how old that page is, because it says &#8220;Because symbols can sometimes be <a href=\"https:\/\/www.cinemablend.com\/news\/1652439\/the-austin-powers-joke-mike-myers-is-really-happy-worked\"> tens of megabytes<\/a> in size\u2026&#8221; Nevermind that the page itself is over a megabyte. (21KB for the main page itself, and the rest is for the fluff around the page, like 263KB for the syntax highlighter JavaScript library and 121KB for the <i>Microsoft Build<\/i> advertisement that was present in early 2021.)<\/p>\n<p>\u00b3 Some time ago, we learned <a href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20200922-00\/?p=104252\"> why cleaning Windows Update files is a CPU-intensive operation<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>They go all over the place.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[26],"class_list":["post-108789","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-other"],"acf":[],"blog_post_summary":"<p>They go all over the place.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/108789","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=108789"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/108789\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=108789"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=108789"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=108789"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}