Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Java Memory Management Charles-François THUEUX Sitraka Inc. [email protected] Overview • Review of Java’s Memory Model • Loitering Objects • Effective Memory Management – Design – Implementation – Documentation • Conclusion and Further Reading Stuttgart JUG 2001 2 Memory Safety in Java • A key aspect in the design of... – the Java Language • no pointer arithmetic – the Java Virtual Machine (JVM) • bytecode instruction set • runtime checks (array bounds, ref casts) • garbage collection Stuttgart JUG 2001 3 Memory Safety in Java • Eliminated many memory-related problems – Buffer overruns – De-referencing stale pointers – Memory leaks • However Java programs can exhibit the macro-level symptoms of traditional memory leaks – Process size seemingly grows without bounds Stuttgart JUG 2001 4 Java’s Memory Model • The intent of Garbage Collection is to remove objects that are no longer needed – Undecidable in general • Java uses an approximation – remove objects that are no longer reachable • The reachability test starts at the Heap’s root set Stuttgart JUG 2001 5 The Root Set • Set of foundational object references – static reference fields within class definitions – local reference variables within the method frames of each Java thread stack • The contents of the Root Set change dynamically as your program runs – As threads enter and exit methods, local reference variables enter and leave the Root Set Stuttgart JUG 2001 6 The Dynamic Root Set - 1 Consider a single thread of execution... 1 public 2 class MyApp 3 { 4 private static MyApp myApp = null; 5 6 public static 7 void 8 main( String[] args ) 9 { 10 myApp = new MyApp( ); 11 myApp.method1( ); Root Set: 12 myApp.method2( ); MyApp myApp String[] args 13 } Stuttgart JUG 2001 7 The Dynamic Root Set - 2 14 15 16 17 18 19 20 21 22 23 24 25 26 27 } private void method1( ) { BigObject bigObj = new BigObject( ); ... Root Set: } MyApp myApp String[] args BigObject bigObj private void method2( ) { BiggerObject biggerObj = new BiggerObject( ); ... } Stuttgart JUG 2001 8 The Dynamic Root Set - 3 1 public 2 class MyApp 3 { 4 private static MyApp myApp = null; 5 6 public static 7 void 8 main( String[] args ) 9 { 10 myApp = new MyApp( ); 11 myApp.method1( ); 12 myApp.method2( ); Root Set: MyApp myApp 13 } String[] args Stuttgart JUG 2001 9 The Dynamic Root Set - 4 14 15 16 17 18 19 20 21 22 23 24 25 26 27 } private void method1( ) { BigObject bigObj = new BigObject( ); ... } private void method2( ) { BiggerObject biggerObj = new BiggerObject( ); ... Root Set: } MyApp myApp String[] args BiggerObject biggerObj Stuttgart JUG 2001 10 The Dynamic Root Set - 5 1 public 2 class MyApp 3 { 4 private static MyApp myApp = null; 5 6 public static 7 void 8 main( String[] args ) 9 { 10 myApp = new MyApp( ); 11 myApp.method1( ); 12 myApp.method2( ); 13 } Root Set: MyApp myApp Stuttgart JUG 2001 11 Reachable Objects • Elements within the Root Set refer to objects within the JVM’s Heap Root Set Object • Reference variables within those objects refer to further objects within the Heap Stuttgart JUG 2001 Reference 12 Object States • Define three progressive object “states” – Allocated • Exists within the JVM’s heap – Reachable • A path exists (directly or indirectly) from a member of the root set, through a sequence of references, to that object. – Live • From the intent of the application’s design, the program will use the object (meaning at least one of its fields will be accessed and/or one of its methods will be invoked) along some future path of execution. Stuttgart JUG 2001 13 The JVM Heap allocated reachable Memory leak in C/C++ (handled by JVM’s GC) “Memory leak” in Java live Stuttgart JUG 2001 14 C/C++ vs. Java • Memory leak in C/C++ – Object was allocated, but it’s not reachable •malloc()/new, but forgot to free()/delete before destroying the memory pointer • “Memory leak” in Java – The object is reachable, but it’s not live • a reference was set, but it hasn’t been eliminated – Object is reachable to the GC, but the source code to fix the leak may not be available to you Stuttgart JUG 2001 15 “Memory Leaks” in Java • Impact is often more severe than C/C++ – Rarely a single object, but a whole sub-graph – A single lingering reference can have massive memory impact (and a significant performance impact) Stuttgart JUG 2001 Unintentional reference 16 Loitering Objects • The term “Memory Leak” has too much historical baggage from C/C++ – and it doesn’t accurately describe the formulation of the problem as it pertains to Java • A new term: Loitering Object – An object that remains within the Heap past its useful life Stuttgart JUG 2001 17 Reference Management • The key to effective memory management in Java is effective reference management • What undermines effective reference management ? – Awareness of the issue – Bad habits from C/C++ development – Class Libraries and Application Frameworks • Ill-defined reference management policies • Encapsulate flawed reference assignments Stuttgart JUG 2001 18 Reference Management • As a Java programmer, how can I effectively manage references within my software, and promote better reference management ? 1. Design 2. Implementation 3. Documentation Stuttgart JUG 2001 19 1. Design for Ref. Mgmt. • For each Use Case within your application, explicitly characterize: a. The lifecycle of each object b. The inter-relationships between various objects Stuttgart JUG 2001 20 Lifecycle Relationships • Object B adopts A’s lifecycle and has no control over it Stuttgart JUG 2001 21 1a. Object Lifecycles • For each object within the Use Case you are implementing, you need to explicitly define: – its point of creation – the duration of its usefulness – the point at which it should be eliminated from the runtime environment Stuttgart JUG 2001 22 1a. Object Lifecycles • In Java, creating an object within the runtime environment is an explicit act, while its elimination is an implicit one • Defining - within your design - the point when your object should be eliminated will help you validate the correctness of your Java implementation Stuttgart JUG 2001 23 1b. Inter-Object Relationships • Objects establish relationships as they collaborate to accomplish their goals • Examples: – Composition (a has-a relationship) – Association (a uses-a relationship) • Relationship lifecycles Stuttgart JUG 2001 24 1b. Inter-Object Relationships • Think “Symmetry” – If you define a method that establishes a relationship, ensure you define a method that revokes it. • The Observer Pattern subject.addObserver( Observer ) subject.removeObserver( Observer ) Stuttgart JUG 2001 25 2. Implementation • Loitering objects often arise from simple coding oversights or omissions – forgot to null-ify a variable – didn’t remove an object from a list • Use a Heap Analysis Tool to validate that your implementation adheres to your design Stuttgart JUG 2001 26 Reference Variable Scope • Three forms of reference variables: – Class-based: • Reference variables within a class definition that have a static attribute associated with them – Object-based: • Non static reference variables within a class definition – Method-based: • Reference variables defined within the scope of a method Stuttgart JUG 2001 27 Reference Variable Scope • Don’t be concerned about assignments to method-based reference variables within methods of short execution time • Be attentive of assignments to classbased and object-based reference variables, and method-based reference variables within methods of long execution times Stuttgart JUG 2001 28 Lingerer • Reference used transiently by long-term object – Reference always reset on next use • e.g. associations with menu items • e.g. global action or service Stuttgart JUG 2001 29 Lingerer Example • Print action as singleton – class Printer… – has data member Printable target; – calls target.doPrint(); – target inside printer not set to null on completion – target is a lingering reference •target cannot be GC’ed until next print Stuttgart JUG 2001 30 Lingerer Strategies • Don’t use a set of fields to maintain state – enclose in object • easier to maintain • one reference to clean up • Draw state diagram – quiescent state == no outgoing references • Early exit methods or multi-stage process – setup; process; cleanup Stuttgart JUG 2001 31 3. Documentation • For methods that establish a relationship to another object, identify (in your javadoc description) the symmetric method that revokes the relationship void addObserver( Observer ) Adds the Observer argument to the subject's internal set of observers. To remove the observer from this internal set, invoke the removeObserver( Observer ) method. Stuttgart JUG 2001 32 Dealing with Flaws of Others • After determining you have a loitering object, your investigation reveals that the object holding the reference to your loiterer is one which you do not have the source code to. • How do you handle this ? Stuttgart JUG 2001 33 Using Their Code Properly ? • Are you using their framework properly ? – Understand their notion of object life cycles • Think symmetry (again) – An add() operation implies a remove() – A register() implies an unregister() – Does the symmetric operation (to the one that established the reference) remove it ? Stuttgart JUG 2001 34 Notify the Author • You’ve established that they are erroneously holding an object reference – Create a simple test case • Make it easy for the vendor to clearly identify the issue. – Ask for • Work arounds (if possible) • Resolution to the fundamental problem Stuttgart JUG 2001 35 Eliminate Subgraph Elements • If you can not fix the root cause, free up as much of the loitering subgraph as you can. Unintentional reference Unintentional reference Stuttgart JUG 2001 36 Conclusion • The key to effective memory management in Java is effective reference management – Incorporate reference management in your design – Validate your Java implementation – Document your reference management policies so others will know what to do Stuttgart JUG 2001 37 Further Reading • Loitering Objects and Java Framework Design by Leonard Slipp, JavaReport, Volume 6, Number 1 (January 2001) http://www.javareport.com/html/from_pages/article.asp?id =249&mon=1&yr=2001 • How Do You Plug Java Memory Leaks ? by Ethan Henry and Ed Lycklama, Dr. Dobb’s Journal, Java Q&A Column,Volume 25, Number 2 (February 2000) www.ddj.com/articles/2000/0002/0002l/0002l.htm • Memory Leaks in Java Programs by Joel Nylund, JavaReport, Volume 4, Number 11 (November 1999). www.javareport.com/archive/9911/html/from_pages/ftp_feat ure.shtml Stuttgart JUG 2001 38