Patterns of Memory Inefficiency Adriana E. Chis 1 , Nick Mitchell 2 , Edith Schonberg 2 , Gary Sevitsky 2 , Patrick O’Sullivan 3 , Trevor Parsons 1 , and John Murphy 1 1 University College Dublin, Dublin, Ireland {adriana.chis,trevor.parsons,j.murphy}@ucd.ie, 2 IBM T.J. Watson Research Center, Hawthorne, NY, US {nickm,ediths,sevitsky}@us.ibm.com 3 IBM Software Group, Dublin, Ireland patosullivan@ie.ibm.com Abstract. Large applications often suffer from excessive memory con- sumption. The nature of these heaps, their scale and complex intercon- nections, makes it difficult to find the low hanging fruit. Techniques rely- ing on dominance or allocation tracking fail to account for sharing, and overwhelm users with small details. More fundamentally, a programmer still needs to know whether high levels of consumption are too high. We present a solution that discovers a small set of high-impact memory problems, by detecting patterns within a heap. Patterns are expressed over a novel ContainerOrContained relation, which overcomes challenges of reuse, delegation, sharing; it induces equivalence classes of objects, based on how they participate in a hierarchy of data structures. We present results on 34 applications, and case studies for nine of these. We demonstrate that eleven patterns cover most memory problems, and that users need inspect only a small number of pattern occurrences to reap large benefits. Keywords: memory footprint, memory bloat, pattern detection, tools 1 Introduction In Java, applications can easily consume excessive amounts of memory [13]. We commonly see deployed server applications consume many gigabytes of Java heap to support only a few thousand users. Increasingly, as hardware budgets tighten, memory per core decreases, it becomes necessary to judge the appropriateness of this level of memory consumption. This is an unfortunate burden on most developers and testers, to whom memory consumption is a big black box. We have spent the past two years working with system test teams that sup- port a family of large Java applications. These teams perform extensive tests of applications, driving high amounts of load against them. While running these tests, they look at gross measures, such as maximum memory footprint. They may have a gut feeling that the number is high, but have little intuition about whether easy steps will have any measurable impact on memory consumption.