What is Strong, Soft, Weak and Phantom Memory References in Java

Understanding various available reference objects in Java is quite important to develop memory sensitive applications, and for memory optimization. Java has four type of memory references which are
  • Strong References,
  • Soft References,
  • Weak References and 
  • Phantom References
However to understand the use of these reference objects, we need to understand in brief that how Java manage the memory, and how it manage the garbage. Please refer to other post at 'How does Java Manage the Memory' to understand that. Now if you are clear with the Java Memory Management Concept, understanding various kind of memory references in Java would be easy for you. The description below is given considering that the readers have read the other post as given above (How does Java Manage the Memory).

Strong Reference: The objects in memory which are referenced from memory stack (without a reference through any other kind of reference) are called strongly referenced. These objects are strongly held by program i.e. in use and hence can not be claimed by GC (Garbage Collector) for memory requirement.

How does Java Manage the Memory

Understanding the Java memory management system is quite important to develop the memory sensitive applications. It also helps us to optimize the usage of memory in our programs. Java maintains a stack to store all object references whichever are being in use by program. Objects actually stores in memory heap and their references are maintained on memory stack.  

Let us try to understand it with some example description. This is not what exactly JVM does, but an example only to simplify the definitions. 

As soon as we create an object in program, its information is being saved to memory with some fixed byte pattern. Now we can use the start of memory location as reference id for this object. In program, there are various kind of scopes defined by Java. These are like code block scope, method level scope, class level scope, package scope and whole program level scope etc.  These scopes generally has parent <> child <> sibling relations with each other. Now as soon as the program scope initialize, a corresponding scope data storage structure (data structure to save the scope variable and other data which will have the memory references of the actual objects in memory) can be made and pushed to memory stack. Similarly other scope structures can be made as soon as they come in existence and can be stored with their parent scope. These scope data structures remain on stack till the corresponding scope is active in program. As soon as, it gets deactivated; the corresponding data structure will be removed from stack. Take it like as program thread enters into a method, we create a scope data structure for method scope and push it to stack with its parent scope which should be class scope. Now as program thread leaves the method, we remove the corresponding scope data from the stack. Scope can interact with each other as per the language protocol because they have parent <> child relationship. This is a simplified version of memory stack with JVM. Now you can visualize scope data structures used to be created or destroyed with the activation or deactivation of corresponding program scope. 

What It means to be a Project Manager

Working as a Project Manager brought a big change in the thinking and work responsibilities. Earlier the focus was on performing any work in best possible manner as an individual, and now the focus is on getting the work done from team in best possible manner. It is a complete shift in paradigm in term of work, daily routine, work planning and thinking. This experience is not entirely new. Everyone used to manage many things while working with a team (even while working as individual contributor). As you gather more experience, you usually manage other junior members of team for their work either technically or from delivery point of view. But the major difference is that now you are focusing more on management and your are liable for work of a group of people, not only for your work. You focus shift from being an individual contributor, to a team mentor or manager (or both), from core development to more broader terms like:
  • Project Planning and Execution
  • Project Scope Management 
  • Project Time and Cost Management
  • Delivery Management 
  • Risk Management
  • Communication Management
  • Resource Planning
  • People Management 
  • Team Building, Mentoring and Recruitment
  • And sometime Procurement Management
These are the traditional work which comes by default in responsibility set of a Project Manager and hence I got these as gift with new job responsibilities. But there are more to add in this list, which is specific to work place requirement and are giving more enriching experience, these are:

Singleton Design Pattern

It is a special class, for which we can not have more than one instance in system at a time. It provides a single global point of access to that instance. Hence it ensures that only one instance can be created for this class and every user is forced to use only that single instance for any operation.


Example

  • Any Utility Class: Generally utility classes do not have states with these and so a single instance of that class can serve the whole system.
  • Memory Manager: An object which is responsible to manage the memory in system. Obviously only there should be only one instance of this object so that it can update the objects with the current memory availability and other objects can update its state for expected memory requirement. 

Factory Design Pattern

It is responsible for creating the objects. As name depicts, it is a factory for creating any specific kind of objects. It abstracts the user from the details of creation mechanism, and also abstracts the actual implementation class of instantiated object. The only requirement is that the ‘object to create’ should be of some already defined type. The actual implementation may differ based on the current scenario.


Example

  • Maruti Car Factory Object: We can ask this object to return us a Maruti car based on any runtime parameter which defines its model like Wagon R, or Esteem. It is the responsibility of this factory object to return us required car implementation based on specific parameters.
  • Row Renderer Factory Object: We can ask it to return the renderer like structured row renderer, or a designable row renderer.

Builder Design Pattern

It separates the construction of complex object from its representation, so that number of different representations can be build based on the requirement. It is similar to factory pattern, but it does not return simple descendant of base class. The factory is concerned with what is made and the builder with how it is made. Factory simply returns an instance of related class of base type, but builder returns a composition of various classes depending on the specified state. 


Example

  • Editor Builder: Suppose you are creating a UI for workflow where a number of different types of nodes can exist. We need different editors to edit these nodes, which can be very complex in structure. Here we can use builder which can build the desired editor.  Even editors can vary in structure based on current state of system.

Prototype Design Pattern

It suggests, instead of creating a new instance of any object, make a copy of existing object and modify its properties as required. Generally cloning is used to create the copy of an existing object. 

Example

  • Drag ‘n Drop: While implementing drag and drop functionality in a UI, we need to show the shadow of items under dragging operation so that user can decide the place to drop the dragged item. Here instead of creating a new instance of item and setting the required properties, best way is to create a prototype of existing object and modify the required properties.
  • Filtered data set using same result set – We retrieved a large data as result set from database. Now we want to show different views on UI based on specified filter criteria. One way is to fetch the same data for every filter criteria, another way is to make the prototype of result set and apply filter to it. It will be less costly than repetitive database access. 

Adapter Design Pattern

Adapter is used to adapt the behavior/functionalities of an existing class but with a different interface.
It can be implemented by two ways, by inheritance (also called class adapter) or by composition (also called object adapter). Either we can extend the existing class and use its functionalities in new interface method, or we can use a reference of existing class in new object for using existing functionalities. 

Example

  • We are making data bound UI components, which are implementing some of our proprietary interface to support the data loading/unloading. But UI components are already defined with Swing library so we want to use these and just want to bind them with data sources. Here we can extend our new components from existing Swing component and implement our data binding interface to it.
  • Use of Window Adapter while intercepting the window closing event. 

Composite Design Pattern

It is a collection of objects, anyone of which can be either a composite or just a primitive object. It enables us to represent a single object or a collection of objects using the same interface.

Example

  • If we are designing a runtime system structure for java program, we can implement it in a tree form where every node can be a executable piece of statement and it may have other nodes in it (which should be executed before it) or may be a leaf node, which just need to execute itself and return the result to the parent (or makes the changes in shared state cache).
  • If we are designing a system to display the employee structuring of an organization. It could be in tree form or in any other form. But designing the data structure using composite pattern can easily manage the requirements for hierarchy structure, where any employee work as individual or may have a number of other employees as sub-ordinates. 

Bridge Design Pattern

It is used to separate the interface from its implementation and enables us to change either interface or implementation easily. Generally it is used to keep the client interface constant and even if we change the implementation.

It seems quite similar to adapter pattern, where we can adapt the functionalities of any other class and expose this with a separate interface. But the difference is in purpose, Adapter is implemented to use the existing implementation with a new interface but Bridge is used to separate the implementation from interface to user so that user won’t be affected by any change in implementation.

Example

  • We want to present some data to user. Based on the user profile, the data can be either in simple list form having names only or in a table having complete details. Here we can implement the logic to fetch the data and arranging it in required format in a separate class which can be accessed from user interface which could be a list, table or tree.