[go: up one dir, main page]

0% found this document useful (0 votes)
97 views53 pages

Memory Leaks in Java Applications: Different Tools For Different Types of Leaks Gregg Sporar Sun Microsystems, Inc

The document discusses different tools and techniques for finding memory leaks in Java applications. It covers observing garbage collection with tools like jvisualvm, inspecting heap dumps to understand object relationships, and using instrumentation to identify objects that may be leaked. The key lessons are that both inspecting heap dumps and using instrumentation each have strengths and weaknesses for leak detection, and that classloader leaks can also cause memory issues.

Uploaded by

Srinivasa Gowda
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
97 views53 pages

Memory Leaks in Java Applications: Different Tools For Different Types of Leaks Gregg Sporar Sun Microsystems, Inc

The document discusses different tools and techniques for finding memory leaks in Java applications. It covers observing garbage collection with tools like jvisualvm, inspecting heap dumps to understand object relationships, and using instrumentation to identify objects that may be leaked. The key lessons are that both inspecting heap dumps and using instrumentation each have strengths and weaknesses for leak detection, and that classloader leaks can also cause memory issues.

Uploaded by

Srinivasa Gowda
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 53

Memory Leaks in Java Applications: Different Tools for Different Types of Leaks Gregg Sporar

Senior Staff Engineer

Sun Microsystems, Inc.

Goal

To understand the different types of tools and techniques available for finding memory leaks.

Agenda What's the Problem? Observing the Problem Inspecting the Heap Using Instrumentation Lessons Learned An Additional Problem... Q&A

Disclaimers
Using Sun's JDK Mostly talking about JDK 5 and 6 The demos use example code

Agenda What's the Problem? Observing the Problem Inspecting the Heap Using Instrumentation Lessons Learned An Additional Problem... Q&A

Have You Ever Seen This?

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

And Then Do Your Users Do This?

So What Do You Do?


Increase the size of the heap

-Xmx64m

-Xmx80m

And hope that the problem is fixed....

But If That Does Not Fix the Problem....


Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at app.leaking.UhOh(leaking.java:41) at app.leaking.WeHadHoped(leaking.java:51) at app.leaking.IfWeKeptIncreasing(leaking.java:55) at app.leaking.TheHeapSize(leaking.java:59) at app.leaking.ThenMaybeThisProblemWouldGoAway(leaking.java:63) at app.leaking.LooksLikeItHasNotGoneAway(leaking.java:67) at app.leaking.Bummer(leaking.java:61) at app.leaking.main(leaking.java:31)

Result: Users Might Get Even Angrier....

Agenda What's the Problem? Observing the Problem Inspecting the Heap Using Instrumentation Lessons Learned An Additional Problem... Q&A

Observing the Problem


java -verbose:gc YourApp

[GC 189K->128K(1984K), 0.0016829 secs] [Full GC 128K->128K(1984K), 0.0108424 secs] [GC 10378K->10368K(12228K), 0.0004978 secs] [Full GC 10368K->10368K(12228K), 0.0097568 secs] [GC 20633K->20608K(28872K), 0.0002025 secs] [Full GC 20608K->20608K(28872K), 0.0097892 secs] [GC 30896K->30848K(36972K), 0.0002380 secs] [Full GC 30848K->30847K(36972K), 0.0641433 secs]

Observing the Problem (continued)

Observing the Problem (continued)


On JDK 1.4.2 or JDK 5: java -Dcom.sun.management.jmxremote YourApp

Observing the Problem (continued)

Observing the Problem (continued)

Observing the Problem (continued)


More Tools in JDK6:

-XX:+HeapDumpOnOutOfMemoryError
(Also available in JDK 1.4.2 and JDK 5)

jhat jmap for Windows Stack trace on OutOfMemoryError


Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at app.leaking.UhOh(leaking.java:41) at app.leaking.WeHadHoped(leaking.java:51) at app.leaking.IfWeKeptIncreasing(leaking.java:55) at app.leaking.TheHeapSize(leaking.java:59) at app.leaking.ThenMaybeThisProblemWouldGoAway(leaking.java:63) at app.leaking.LooksLikeItHasNotGoneAway(leaking.java:67) at app.leaking.Bummer(leaking.java:61) at app.leaking.main(leaking.java:31)

Agenda What's the Problem? Observing the Problem Inspecting the Heap Using Instrumentation Lessons Learned An Additional Problem... Q&A

Case Study: A Swing Application


Production Planning application Developed during 1999-2002 JDK 1.2 (later moved to JDK 1.3 and then 1.4) ~263,000 LOCs ~1,600 Classes Memory leak found during QA, right before going live Easy to reproduce the problem, with the right data, but still not obvious what the cause was

DEMO

Inspecting the Heap With a Profiler

So What Happened?
A bug in someone else's code prevented garbage collection of my objects 4215796: RepaintManager DoubleBuffer can cause leak...

My Swing control

Swing var Tree model

Domain model

So What Happened? (cont'd)


Easy to work around once you know the problem....

My Swing control

Swing var Tree model

Domain model

Agenda What's the Problem? Observing the Problem Inspecting the Heap Using Instrumentation Lessons Learned An Additional Problem... Q&A

Case Study: A Web Application


Hardware/software analysis system Developed during 2000-2004 JDK 1.? (Later moved to JDK 1.4) >150,000 LOCs, which does not include:

the JSPs a subsystem written in Perl


Memory leak found in the live, production system Hard to reproduce the problem - seemed to occur randomly

DEMO

Using Instrumentation

So What Happened?
Multiple places in the code were allocating AnalysisResults objects, but only some of those allocations were causing leaks.

HashMap

: AnalysisResult allocated by the foreground process : AnalysisResult allocated by the background process

So What Happened? (continued)


The foreground code always removed its entries from the HashMap. The background code never removed its entries.

HashMap

: AnalysisResult allocated by the background process

How Does Generation Count Help?


One Example of Healthy Behavior:

Long-lived objects. Example: Three object instances created at startup. Their ages continue to increase, but generation count remains stable (at 1)

How Does Generation Count Help?


Another Example of Healthy Behavior:

Short-lived objects Example: Create an object, use it and then immediately let go of all references to it. Generation count remains stable (at 1)

How Does Generation Count Help?


Unhealthy Behavior (a Memory Leak):
Example: Continue to allocate objects without letting go of all references. Ten objects with eight different ages. Generation count is always increasing.

Agenda What's the Problem? Observing the Problem Inspecting the Heap Using Instrumentation Lessons Learned An Additional Problem... Q&A

Lessons Learned
Plenty of good, free tools available that provide a high-level view of the memory used by a Java application Beyond that, there are two broad categories:

Inspecting the Heap Instrumentation

Lessons Learned (continued)


Inspecting the Heap
Strengths: Less impact on performance Easy to see relationships between objects Weaknesses: No information about how the objects got onto the heap or whether they should still be there Large heap size can lead to information overload Can be tough to use if you don't know the code

Instrumentation
Strengths: Identifies objects that are candidate memory leaks Does not require as much knowledge of the code Scales well Weaknesses: Introduces runtime overhead Does not show relationships between the objects

Agenda What's the Problem? Observing the Problem Walking the Heap Using Instrumentation Lessons Learned An Additional Problem... Q&A

Have You Ever Seen This?


Exception in thread "main" java.lang.OutOfMemoryError: Java heap space Exception in thread "main" java.lang.OutOfMemoryError: PermGen full

These Guys Have....

http://blogs.sun.com/fkieviet/entry/javaone_2007 http://blogs.sun.com/edwardchou/entry/javaone_bof_on_ memory_leaks

The basics: heap memory generations

Young

Tenured

Permanent

Usually referred to as the heap. Controlled by -Xmx and -Xms

Used by the JVM to store classes. Controlled by -XX: MaxPermSize and -XX:PermSize

The basics: classes and classloaders


Each object is an instance of a class A class itself is an object (class object)

instance of the class Class


Each class object references its classloader A classloader references all classes it loaded Class objects hold static members

The basics: classes and classloaders

* 1

java.lang.Class statics 1 * java.lang.Object *

java.lang.ClassLoader

Why use classloaders?


Containers use classloaders to

dynamically load applications isolate applications from each other dynamically unload applications

Example: empty servlet


package com.stc.test; import import import import java.io.*; java.net.*; javax.servlet.*; javax.servlet.http.*;

public class Servlet1 extends HttpServlet { private static final String STATICNAME = "Simple"; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // nothing } }

Deployed

Undeployed

Classloader leaks
A classloader cannot be garbage collected if any of the instances of any of the classes it loaded are reachable. Such a classloader keeps all its classes with all their static members in memory.

Not immediately apparent from a memory dump


what is a leak and what is not.

Cause of the leak difficult to find.

Example: a leaking servlet


package com.stc.test; import import import import java.io.*; java.util.logging.*; javax.servlet.*; javax.servlet.http.*;

public class LeakServlet extends HttpServlet { private static final String STATICNAME = "Leak!"; static Level CUSTOMLEVEL = new Level("OOPS", 555) {}; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Log at a custom level Logger.getLogger("test").log(CUSTOMLEVEL, "x called"); } }

Deployed

java.util.logging.Level class
private static List known = new ArrayList(); protected Level(String name, int value) { this.name = name; this.value = value; synchronized (Level.class) { known.add(this); } }

A Leak... These 2 are taking up space in PermGen

Undeployed

Reality:
Hundreds or Thousands of leaked classes Thousands of leaked objects Bafflement...

Java Profilers
Take memory snapshots Find reference chains to GC root objects Most see class objects as GC root objects so they are not very helpful

DEMO

Inspecting the Heap With jhat

Agenda What's the Problem? Observing the Problem Walking the Heap Using Instrumentation Lessons Learned An Additional Problem... Q&A

Resources
April, 2007 issue May, 2007 issue

Both available at http://www.stpmag.com/

Q&A

gregg.sporar@sun.com

You might also like