Garbage Collection and Classloading Java Garbage Collectors Eden
Garbage Collection and Classloading Java Garbage Collectors Eden Space Surviver Space Tenured Gen Perm Gen Garbage Collection Notes Classloading Classloader Family Tree The Rules of Classloading Custom Classloading Breaking the Rules
Java Garbage Collectors 1/2 There are two basic types of Garbage Collector Stop the world garbage-collectors Non-blocking garbage-collectors All threads are suspended Garbage collection is performed All threads are re-started Execution is sometimes suspended for a short time before garbage collection is actually performed Java has 4 memory spaces or “heaps” Objects are allocated, and promoted from one space to the other, the longer they live
Java Garbage Collectors 2/2 There are 3 different “Generations” in Java Young Generation, divided into 3 spaces Tenured Generation Eden Space Surviver From Space Surviver To Space For objects that are in current use Perm Generation For VM objects and byte-code objects The VM's “Main” thread The System Classloader java. lang. reflect
Eden Space 1/4 All Objects and primitives are allocated here Uses a “copy” garbage-collector Copy is a stop-the-world collector Two equal sized heaps Allocate all data into the “active” heap When the active heap is full, copy the live objects into the inactive heap The inactive heap becomes the inactive heap Eden space is the smallest heap This means that Eden space is frequently garbage collected
Eden Space 2/4 Advantages of a copy garbage collector Very simple form of collection Simple means it's fast It has a “stack and compact” effect Data is always allocated on top of the heap When garbage collection occurs: all the live objects are compacted to the bottom of the heap Disadvantages It's stop-the-world, nothing can execute while collection is happening Uses 2 heaps, and so double the memory
Eden Space 3/4 (Copy Collection) Allocate Object A c t i v e Copy active objects Stop the world A c t i v e Allocate Object A c t i v e Active Heap is Full A c t i v e Swap Active Heap A c t i v e Restart the world
Eden Space 4/4 (Summary) Because Eden space is small, it is garbage collected often Eden space uses a stop the world garbage collector, but is very fast and so no effect is really visible on application performance Eden space may grow to accommodate larger or more objects Both heaps will always be kept to the same size After garbage-collection, all remaining objects are moved to “Surviver Space”
Surviver Space 1/2 Contains objects that “survived” the Eden space Objects that are not garbage-collected by the Eden space collector Surviver Space is treated the same as Eden space and is also a Copy based garbage-collector Surviver Space is larger than Eden space, and is tuned to flush out the short-lived objects that “escaped” collection in Eden space
Surviver Space 2/2 Surviver Space is divided into 2 parts From Space – Treated much the same as Eden space To Space – Where objects that survive Eden, and From Space are allocated to When the To space is filled with objects The To space is garbage collected The remaining objects are promoted to the “Tenured Gen”
Tenured Gen 1/3 When Surviver To Space is filled up, the live objects are promoted to Tenured Gen is collected with a “mark-sweepcompact” Garbage Collector Most “long lived” objects exist in Tenured space Garbage Collection of Tenured space causes a very short pause of execution to determine the “root” objects Tenured space is Garbage Collected by default when it is 68% full
Tenured Gen 2/3 The “mark-sweep-compact” Garbage Collector only pauses execution to find the “root” objects The Garbage Collector traverses the object graph from the root objects while execution continues Root objects are those that are directly accessible by one or more currently executing thread Objects that are traversed over are marked as active Objects that are not marked will be garbage collected The Garbage Collector doesn't move objects during execution, so “holes” are left in the heap
Tenured Gen 3/3 When no more objects can be allocated into the Tenured Gen it does a “stop the world” collection All threads are suspended The Garbage Collector runs Remaining objects are reshuffled to be at the bottom of the heap Threads are re-started Tenured Gen is the largest space It takes the longest to Garbage Collect It is to large for a “copy” Garbage Collector The “mark-sweep-compact” collector operates early
Perm Gen is the “permanent” space in the VM Used to store class byte-codes The Virtual Machine's “Main” thread Reflection objects You can generally assume that Perm Gen is never Garbage Collected This causes problems with Class. Loaders, since each Class. Loader may load it's own copy of a single class The most visible symptom is an Out. Of. Memory. Exception from application servers
Garbage Collection Notes Primitives in Java are not references Local variable “slots” are re-used by the compiler to reduce the number of variables Java 1. 6 further optimizes Garbage Collection by having the compiler hint at when to Garbage Collect certain variables (scoping) The Garbage Collectors are very well tuned to most situations, but can be tuned using options The JConsole gives a good overview of memory usage and can also monitor a remote VM
Garbage Collection End Questions and Coffee Break
Classloading Classloader Family Tree The Rules of Classloading Custom Classloading Breaking the Rules
Classloader Family Tree 1/2 Bootstrap Classloader is used to load the System Class. Loader System. Class. Loader is used to load all other classes All Classes have a parent Class. Loader Any Class accessed by the Class is requested from it's parent Class. Loader The parent Class. Loader always loaded the class Each Class. Loader also has a parent Class. Loader, this is normally the parent Class. Loader of the Class that instantiated the Class. Loader
Class. Loader Family Tree 2/2 Class. Loaders can access the Classes of their parent Class. Loader, but not of their child Class. Loaders Think about the relationship between a normal Class and it's parent Class. Loader System Class. Loader Custom Child Class. Loader
The Rules of Class. Loading 1/2 Override the find. Class method rather than load. Class If overriding load. Class: call super. load. Class before attempting to resolve the Class yourself This ensures that “java. *” packages cannot be overridden Also helps conserves memory by making sure that a minimal set of Classes are loaded at any given time Class. Loaders should also implement the find. Resource method for get. Class(). get. Resource
The Rules of Class. Loading 2/2 Classes are always loaded using the load. Class method The default implementation resolves the class by: 1. Invoke Class. Loader. find. Loaded. Class(String) to check if the class has already been loaded. 2. Invoke the load. Class method on the parent class loader. If the parent is null the class loader built-in to the virtual machine is used, instead. 3. Invoke the find. Class(String) method to find the class.
Custom Class. Loading 1/2 public class Custom. Class. Loader extends Class. Loader { private File directory; . . . protected Class<? > find. Class(String name) throws Class. Not. Found. Exception { String class. File. Name = name. replace('. ', '/') + “. class”; File class. File = new File(directory, class. File. Name); if(!class. File. exists() || !class. File. is. File()) { throw new Class. Not. Found. Exception(); } else { try { byte[] bytecode = new byte[(int)class. File. length()]; File. Input. Stream fin = new File. Input. Stream(class. File); int length = fin. read(bytecode); fin. close(); return define. Class(name, bytecode, 0, length); } catch(IOException ioe) { throw new Class. Not. Found. Exception(“Error loading class”, ioe); } }
Custom Class. Loading 2/2 As you can see, custom Class. Loading is very simple Caching of already loaded class is done in load. Class Finding alternative Class's is done in load. Class Verification of bytecodes is done in define. Class All you do is load the bytecode into an array and pass it to define. Class To access a class loaded with a custom Class. Loader, use load. Class(full. Class. Name) and normal reflection to construct the object
Breaking the Rules Breaking the Class. Loading rules allows you to override standard and already-loaded Class's To break the rules, you will generally override the load. Class(String, boolean) method of Class. Loader Allows you to override standard API's Don't call super. load. Class Allows you to overwrite already loaded classes Don't make a call to find. Loaded. Class The old bytecode will exist so long as there is still a reference to an object of the old type
Questions If there any?
- Slides: 24