Java Memory Management
I will begin our blog on Java Tutorial with an incredibly important aspect of java development: memory management. The importance of this topic should not be minimized as an application's performance and footprint size are at stake.
From the outset, the Java Virtual Machine (JVM) manages memory via a mechanism known as Garbage Collection (GC). The Garbage collector
- Manages the heap memory. All obects are stored on the heap; therefore, all objects are managed. The keyword, new, allocates the requisite memory to instantiate an object and places the newly allocated memory on the heap. This object is marked as live until it is no longer being reference.
- Deallocates or reclaims those objects that are no longer being referened.
- Traditionally, employs a Mark and Sweep algorithm. In the mark phase, the collector identifies which objects are still alive. The sweep phase identifies objects that are no longer alive.
- Deallocates the memory of objects that are not marked as live.
- Is automatically run by the JVM and not explicitely called by the Java developer. Unlike languages such as C++, the Java developer has no explict control over memory management.
- Does not manage the stack. Local primitive types and local object references are not managed by the GC.
So if the Java developer has no control over memory management, why even worry about the GC? It turns out that memory management is an integral part of an application's performance, all things being equal. The more memory that is required for the application to run, the greater the likelihood that computational efficiency suffers. To that end, the developer has to take into account the amount of memory being allocated when writing code. This translates into the amount of heap memory being consumed.
Memory is split into two types: stack and heap. Stack memory is memory set aside for a thread of execution e.g. a function. When a function is called, a block of memory is reserved for those variables local to the function, provided that they are either a type of Java primitive or an object reference. Upon runtime completion of the function call, the reserved memory block is now available for the next thread of execution. Heap memory, on the otherhand, is dynamically allocated. That is, there is no set pattern for allocating or deallocating this memory. Therefore, keeping track or managing this type of memory is a complicated process. In Java, such memory is allocated when instantiating an object:
String s = new String(); // new operator being employed String m = "A String"; /* object instantiated by the JVM and then being set to a value. The JVM calls the new operator */
In the String example above, a String object is being created in both cases and placed on the heap. In the first case, we employ the new operator to instantiate the String; in the second case, this call is made by the JVM behind the scenes.
The process of instantiating an object is quite expensive and occurs via the following steps:
- Heap memory is allocated.
- Instance fields are set to their default values.
- Initialization blocks are called.
- The object's constructor is called.
- The object's super constructor is called.
- Superclass instance fields are given specified values.
- The body of the super class constructor is called.
- ... repeat necessary steps above fall all super classes.
Obviously, instantiating an object or acquiring heap memory can a very costly process. So how do we minimize this cost? Below are some examples of how to minimize and application's heap dependency.
Keep Object Instantiation to a Minimum
Work with primitives instead of objects.
int k = 0; // places an int, declared locally, on the stack Integer K = new Integer(k); //places an Integer object on the heap a comparatively costly process. /* Be careful of autoboxing. In the method below, having an object as a parameter will automatically convert a primitive type to an object */ public class MemoryExample { public void someMethod(Object o){ ... } public static void main(String[] args){ MemoryExample me = new MemoryExample(): int m = 4; me.someMethod(m); //converts m to an Integer } /* consider creating someMethod() as follows: public void someMethod(int i) { ... } this will avoid autoboxing altogether since the primitive int will not force the JVM to instantiate an object. */ }
Create classes that do not need to be instantiated.
When reading the documentation on the Java Math class, you should notice that all of the member variables and methods are class fields and class methods respectively. This means that the developer does not have to instantiate a Math object whenever making a computation. Just think of the object overhead or memory footprint if the application were to do one to two thousand computations per minute. Also, notice that the Math class excepts primitives so boxing is not a concern. If this were not to be the case, then memory requirements would be compounded by the creation of wrapper objects such as Integer, Decimal and the like.
To create your own class that uses static methods, declare methods and fields to be static.
public class EmployeeSalaryComp{ public final static double annualBonusPercentage = 4.2531; public static double employeeRaise(double salary){ return salary * (annualBonusPercentage/100); } } //when invoking EmployeeSalaryComp, an object does not need to be created ... EmployeeSalaryComp.employeeRaise(johns_salary);
Avoid String Concatenation
Be careful not to use the string concatenation (+) operator when working with strings and use StringBuilder or StringBuffer instead. Every time you concatenate a String, you are creating another object. This is due to the fact that strings are immutable and therefore force the contenation operator to create a new String that is the contenation of two other strings. StringBuilder and StringBuffer, on the other hand, will append one String to anther and not create a new String.
String s = new String("Java Training"); s += " is great"; /*The String concatenation operation above will result in the creation of an additional String*/ StringBuffer sb = new StingBuffer("Java Training"); sb.append(" is great"); // or StringBuilder sbuild = new StringBuilder("Java Training"); sbuild.append(" is great."): /* StringBuilder was added in Java 5.0 to provide a non-synchronized version of StringBuffer and is, therefore, the preferred way to concatenate strings when thread saftey is not a concern as it is faster than StringBuffer. */
Set Unused Object References to null
Although we cannot explicitly manage memory, we can help the GC work more efficiently. Take a look at the example below.
//C++ example Object a = new Object(); delete a; //Java example Object a = new Object(); a = null;
In C++, memory management is achieved explicity by use of the delete operator. Although Java has no equivalent, setting references to objects that are no longer needed will aid the garbage collector to reclaim the memory to which they refer.
Instantiate a Singleton or Work with Object Pools
Wherever possible, reuse objects that have already been created. The Spring Framework delivers on that promise as should you. Create only one object of a certain type and pass it around to various execution threads to be used over and over again. Use object pools as well, in particular, when working with database connection objects. If the JVM had to create a database call for each sql query, think of all the overhead that is incurred.
Stack and Heap in Java - a Clarification
As is shown in the example below, all instantiated objects are placed on the heap. This includes the value of their primitive members as well. In MemoryExample, intmember is placed on the heap. The reference objectmember is also placed on the heap as is the object to which it refers. As for local variables, i.e. those declared within the method of a class, primitive types and object references are placed on the stack. The objects to which these local references refer, however, are placed on the heap.
public class MemoryExample{ private int intmember = 2; //reference stored on heap with the MemoryExample reference. private Object objectmember = new Object(); // a is a reference to a literal object that has been placed on the heap. public void someMethod(){ int localprimitive = 4; // placed on the stack because it refers to a java primitive type Object localobject = new Object(); /* references an object placed on the heap eventhough the variable is declared as a variable local to the method, someMethod(). The reference, localobject, is placed on the stack. */ }}
other blog entries
Course Directory [training on all levels]
- .NET Classes
- Agile/Scrum Classes
- Ajax Classes
- Android and iPhone Programming Classes
- Blaze Advisor Classes
- C Programming Classes
- C# Programming Classes
- C++ Programming Classes
- Cisco Classes
- Cloud Classes
- CompTIA Classes
- Crystal Reports Classes
- Design Patterns Classes
- DevOps Classes
- Foundations of Web Design & Web Authoring Classes
- Git, Jira, Wicket, Gradle, Tableau Classes
- IBM Classes
- Java Programming Classes
- JBoss Administration Classes
- JUnit, TDD, CPTC, Web Penetration Classes
- Linux Unix Classes
- Machine Learning Classes
- Microsoft Classes
- Microsoft Development Classes
- Microsoft SQL Server Classes
- Microsoft Team Foundation Server Classes
- Microsoft Windows Server Classes
- Oracle, MySQL, Cassandra, Hadoop Database Classes
- Perl Programming Classes
- Python Programming Classes
- Ruby Programming Classes
- Security Classes
- SharePoint Classes
- SOA Classes
- Tcl, Awk, Bash, Shell Classes
- UML Classes
- VMWare Classes
- Web Development Classes
- Web Services Classes
- Weblogic Administration Classes
- XML Classes
- VMware vSphere 8.0 with ESXi and vCenter
9 December, 2024 - 13 December, 2024 - VMware vSphere 8.0 Boot Camp
9 December, 2024 - 13 December, 2024 - Introduction to Spring 5 (2022)
16 December, 2024 - 18 December, 2024 - Ruby on Rails
5 December, 2024 - 6 December, 2024 - RED HAT ENTERPRISE LINUX AUTOMATION WITH ANSIBLE
2 December, 2024 - 5 December, 2024 - See our complete public course listing
did you know? HSG is one of the foremost training companies in the United States
Our courses focus on two areas: the most current and critical object-oriented and component based tools, technologies and languages; and the fundamentals of effective development methodology. Our programs are designed to deliver technology essentials while improving development staff productivity.
An experienced trainer and faculty member will identify the client's individual training requirements, then adapt and tailor the course appropriately. Our custom training solutions reduce time, risk and cost while keeping development teams motivated. The Hartmann Software Group's faculty consists of veteran software engineers, some of whom currently teach at several Colorado Universities. Our faculty's wealth of knowledge combined with their continued real world consulting experience enables us to produce more effective training programs to ensure our clients receive the highest quality and most relevant instruction available. Instruction is available at client locations or at various training facilities located in the metropolitan Denver area.
Upcoming Classes
- VMware vSphere 8.0 with ESXi and vCenter
9 December, 2024 - 13 December, 2024 - VMware vSphere 8.0 Boot Camp
9 December, 2024 - 13 December, 2024 - Introduction to Spring 5 (2022)
16 December, 2024 - 18 December, 2024 - Ruby on Rails
5 December, 2024 - 6 December, 2024 - RED HAT ENTERPRISE LINUX AUTOMATION WITH ANSIBLE
2 December, 2024 - 5 December, 2024 - See our complete public course listing
consulting services we do what we know ... write software
The coaching program integrates our course instruction with hands on software development practices. By employing XP (Extreme Programming) techniques, we teach students as follows:
Configure and integrate the needed development tools
MOntitor each students progress and offer feedback, perspective and alternatives when needed.
Establish an Action plan to yield a set of deliverables in order to guarantee productive learning.
Establish an Commit to a deliverable time line.
Hold each student accountable to a standard that is comparable to that of an engineer/project manager with at least one year's experience in the field.
These coaching cycles typically last 2-4 weeks in duration.
Business Rule isolation and integration for large scale systems using Blaze Advisor
Develop Java, .NET, Perl, Python, TCL and C++ related technologies for Web, Telephony, Transactional i.e. financial and a variety of other considerations.
Windows and Unix/Linux System Administration.
Application Server Administration, in particular, Weblogic, Oracle and JBoss.
Desperate application communication by way of Web Services (SOAP & Restful), RMI, EJBs, Sockets, HTTP, FTP and a number of other protocols.
Graphics Rich application development work i.e. fat clients and/or Web Clients to include graphic design
Performance improvement through code rewrites, code interpreter enhancements, inline and native code compilations and system alterations.
Mentoring of IT and Business Teams for quick and guaranteed expertise transfer.
Architect both small and large software development systems to include: Data Dictionaries, UML Diagrams, Software & Systems Selections and more