DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Coding
  3. Languages
  4. Diagnosing Memory Leaks in Managed Windows Store Apps

Diagnosing Memory Leaks in Managed Windows Store Apps

Sasha Goldshtein user avatar by
Sasha Goldshtein
·
Oct. 18, 12 · Interview
Like (0)
Save
Tweet
Share
7.42K Views

Join the DZone community and get the full member experience.

Join For Free

there is so much material on the web (and even on this blog) about memory leak diagnostics in managed code, and a considerable number of tools that make diagnostics increasingly easier. modern memory profilers can open application dumps, attach to live processes, display live memory graphs, compare snapshots, identify problematic retention patterns, and so much more.

unfortunately, these tools presently don’t work with windows store apps. moreover, the ui model of windows store apps poses a significant challenge in diagnosing many ui-related memory leaks, such as composite ui controls retaining objects embedded in them, or ui elements retaining objects registered to their events.

namely, the windows store app ui framework is implemented in unmanaged code and exposed to c# apps through fairly standard com interop (with some minor tweaks). because the garbage collector has no insight into or control over unmanaged com objects in the windows runtime, tracing a memory leak to its true source becomes exceptionally difficult. needless to say, the lack of profiler support does not help – you need to pull the trusty windbg and sos combination for even the simplest of problems.

to begin with, you can’t reliably keep windbg attached to a windows store app. it seems that windows detects that the app is not running, and eventually terminates it under the nose of the debugger. this isn’t that big a deal – you have to resort to dump files instead. (on windows 8, task manager can capture dumps for you; just make sure you capture dumps of 32-bit apps using the 32-bit task manager, and vice versa.)

image

consider an app that consumes a large amount of memory because it has a listview with many large objects retained by it. the standard leak diagnostic commands produce the following:

image

0:006> !dumpheap -stat
…edited for brevity…
3077ce04       14          224 windows.ui.xaml.controls.listboxitem
3077ee2c       15          240 windows.ui.xaml.data.binding
005e5f00       14          392 memoryleakingstoreapp.bigobject
5b6d7940        7          420 system.reflection.runtimemethodinfo
5b6d7180        5          420 system.runtimetype+runtimetypecache
5b6a1e64       18          432 system.runtime.interopservices.windowsruntime.windowsruntimemarshal+nativeorstaticeventregistrationimpl+eventregistrationtokenlistwithcount
309d0af4       14          448 windows.ui.xaml.controls.selectionchangedeventhandler
5ab845ec       17          476 system.uriparser+builtinuriparser
5b6a1094        5          600 system.runtime.compilerservices.conditionalweaktable`2+entry[[system.object, mscorlib],[system.runtime.interopservices.windowsruntime.windowsruntimemarshal+nativeorstaticeventregistrationimpl+eventregistrationtokenlistwithcount, mscorlib]][]
5b6dd690        2          616 system.globalization.culturedata
5ab845a4        2          952 system.collections.generic.dictionary`2+entry[[system.string, mscorlib],[system.uriparser, system]][]
5b6dc738       15          988 system.int32[]
5b6a0d40       94         1504 system.runtime.interopservices.windowsruntime.icustompropertyproviderproxy`2[[system.object, mscorlib],[system.object, mscorlib]]
5b6dc168       55         1540 system.runtimetype
5b6dafb0      205         9996 system.string
5b68ae88       30        18076 system.object[]
008a0dd8      125        32450      free
5b6dd244       29     21000348 system.byte[]

ok, so at this point we know that we have a small number of byte arrays that consume a bunch of memory. a typical root chain for the larger ones looks like this:

0:006> !gcroot 04393620
handletable:
00541478 (ref counted handle)
-> 025471e8 system.runtime.interopservices.windowsruntime.icustompropertyproviderproxy`2[[system.object, mscorlib],[system.object, mscorlib]]
-> 02546bf8 windows.ui.xaml.controls.itemcollection
-> 0254b734 memoryleakingstoreapp.bigobject (dependent handle)
-> 04393620 system.byte[]

that is to say, the byte arrays are retained by bigobject instances, which are held by a xaml itemscollection. but which objects holds this collection? it remains a mystery behind the icustompropertyproviderproxy generic interop interface… now surely, itemscollection points in the general direction of the user interface, and hints pretty strongly that some kind of items control is involved. but there is no way to determine which – the mysterious answer is behind the great wall of interop.

similarly, suppose you have a bunch of objects registered for an event of a ui control, such as listview.selectionchanged. here’s what the reference chain will look like in the debugger:

0:006> !gcroot 0c0935d0
handletable:
005418f8 (ref counted handle)
-> 0254d22c windows.ui.xaml.controls.selectionchangedeventhandler
-> 0254d220 memoryleakingstoreapp.myhandler
-> 0c0935d0 system.byte[]

as before, the useful part terminates at the selectionchangedeventhandler object. it is retained by a ccw (com-callable wrapper), and you don’t know how to proceed behind the great wall. yes, you have the hint of “selectionchangedeventhandler”, but if you have many ui controls on the page, or pages that your app may have retained from past navigations, this still doesn’t help much.

interestingly, you can always discern between an event handler (or any ccw reference in fact) retained by the xaml framework (“jupiter”) as opposed to a standard ccw reference from com or a non-ui windows runtime component. to do so, find the ccw address for your managed object and run !dumpccw . for example:

0:000> !do -nofields 02028c28
name:        memoryleakingstoreapp.bigobject
methodtable: 003d5f00
eeclass:     05d0179c
ccw:         0065f240
size:        28(0x1c) bytes

0:000> !dumpccw 0065f240
managed object:    02028c28
outer iunknown:    00000000
ref count:         0
flags:
jupiter ref count: 8, pegged by jupiter & clr
refcounted handle: 002d17f8 (strong)
com interface pointers:
ip       mt type

to conclude, memory leak diagnostics have just become much more interesting (read: more difficult) with windows store apps, especially when any windows runtime objects are involved. because your c# code is now playing in a largely-unmanaged field, with com objects retaining .net objects, which in turn retain other com objects, there’s plenty of new types of leaks and nasty interop scenarios to be worried about.

there hasn’t ever been a better time to take an “introduction to com” course since the late ‘90s :-)

app Memory (storage engine) Object (computer science)

Published at DZone with permission of Sasha Goldshtein, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Top 10 Secure Coding Practices Every Developer Should Know
  • 5 Factors When Selecting a Database
  • Better Performance and Security by Monitoring Logs, Metrics, and More
  • Load Balancing Pattern

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: