JPA - Hello, World! using Hibernate 5

The article JPA - Hello, World! using Hibernate explains how to use Hibernate v4.x. This tutorial introduces using JPA with the latest Hibernate v5.2.3. Same as the previous article, it also targets beginners who are new to Hibernate and JPA.

You need Java 1.8, Eclipse for Java EE developers and MySQL server in your system in-order to try this tutorial.

Step 1:
Create a database “javahelps” and a table “student” in MySQL.
CREATE DATABASE IF NOT EXISTS javahelps;

CREATE  TABLE javahelps.student ( 
student_id INT NOT NULL ,
student_name VARCHAR(45) NOT NULL ,
student_age INT NOT NULL ,
PRIMARY KEY (student_id) );

Read More

WSO2 CEP - Output Mapping Using Registry Resource

Publishing the output is an important requirement of CEP. WSO2 CEP allows to convert an event to TEXT, XML or JSON, which is known as output mapping . This article explains how a registry resource can be used for custom event mapping in WSO2  CEP 4.2.0.


Step 1:
Start the WSO2 CEP and login to the management console.

Step 2:
Navigate to Home → Manage → Events → Streams → Add Event Stream.

Step 3:
Define an event stream as given below and click on ‘Add Event Stream’ button.
Name: sensorstream
Version: 1.0.0
Meta Data Attributes: sensorId, sensorName and language
Correlation Data Attributes: longitude and latitude
Payload Data Attributes: sensorValue


Step 4:
Navigate to Home → Registry → Browse.

Step 5:
Expand the /_system/config tree view and click on the config folder.

Step 6:
Click on the Add Collection link and add a new collection named template.


Step 7:
Same as Step 6, create another sub folder en inside the template folder.

Step 8:
Click on the ‘Add Resource’ button and select ‘Create Text Content’ as the method. This means that we are going to provide a content that is readable for human.
Provide the name as message and leave the Media type as text/plain. Suppose you want to create an XML or JSON resource, change the media type to application/xml or application/json respectively.

Step 9:
Add the content that matches your media type and click the Add button.


The message used in this screenshot is given below:
Welcome
Sensor {{meta_sensorName}} reports {{sensorValue}} from {{correlation_longitude}}:{{correlation_latitude}}

Step 10:
Navigate to the Home → Manage → Event → Publishers and click on the Add Event Publisher button.

Step 11:
Provide samplelogger as the publisher name, sensorstream:1.0.0 as the event source, logger as the output event adapter type and text as the message format. If your registry resource is XML or JSON, change the message format to your media type.

Then expand the Advanced configuration and select ‘Pick from registry’.
Click on the ‘Configuration Registry’ button, browse and select the message resource.


Leave the Cache Timeout with the default value.

Compare your configuration with the following screenshot.


Finally click the Add button.

Step 12:
Now move to the  Home → Tools → Event Simulator and select the sensorstream:1.0.0 as the events stream name.
Fill the form as shown below and click the send button.
sensorId: 10
sensorName: Temperature
language: en
longitude: 79.861256
latitude: 6.927131
sensorValue: 23.0


Once you clicked the Send button, you should get the following output in the terminal of CEP.



Parametrized Registry Path
WSO2 CEP allows you to parameterize the registry path as well. For example, assume that we want to select a registry resource depending on the meta_language. For this purpose, we need another registry resource.

As you did in Step 4 – 9, cerate a new folder named fr in /_system/config/template and a resource named message in /_system/config/template/fr folder.


The message used in this screenshot is given below:
Bienvenue
Sensor {{meta_sensorName}} reports {{sensorValue}} from {{correlation_longitude}}:{{correlation_latitude}}

Now the registry should contain both en/message and fr/message.


Step 13:
Delete the existing samplelogger publisher and create a new one using the same name as shown in Step 11. But this time, provide the following path as the registry path.
conf:/template/{{meta_language}}/message
Compare this path with the path in Step 11. Instead of hard coding the language folder name en or fr, the attribute meta_language is used. At the runtime, the meta_language will be replaced by the actual language name and the resource at that path will be used by the publisher.


Step 14:
Repeat the Step 12 with languages en, fr and something other than English and French.
In the terminal, CEP will print the message in English and French according to the input and thrown an exception if the resource for the given language does not exists.


If the registry does not contain a resource at the run time evaluated path, an exception will be thrown.

For more details about output mapping, visit to the official document: Output Mapping Types
Read More

Never Duplicate A Window Again - WSO2 Siddhi Event Window

A new feature known as Event Window is introduced in WSO2 Siddhi 3.1.1 version, which is quite similar to the named window of Esper CEP in some aspects. This article presents the application and the architecture of Event Window using a simple example. According to Siddhi version 3.1.0, a window can be defined on a stream inside a query and the output can be used in the same query itself. For example, consider a scenario where WSO2 CEP is used to analyze the sensor reading of a smart home which has multiple sensors in number of rooms. All the sensors are sending their reading to an input stream named SensorStream and there are different analytics components interested in various statistic information.

If there are two analytic components named A and B which are interested in the maximum reading of each sensors in every room in last 5 seconds and the average sensor reading of each type of sensors in the smart home in last 5 seconds respectively, it can be achieved using a query provided below.
define stream SensorStream (name string, value float, roomNo int, deviceID string);

@info(name = 'query0')
from SensorStream#window.timeBatch(1 second)
select name, max(value) as maxValue, roomNo
group by name, roomNo
insert into MaxSensorReadingPerRoomStream;

@info(name = 'query1')
from SensorStream#window.timeBatch(1 second)
select name, max(value) as maxValue, roomNo
group by name, roomNo
insert into AverageSensorReadingPerBuildingStream;
In this definition, the events arrived in last second will be stored in two windows which are identical  to each other. The output is determined only by the selection and grouping. If the time interval is large enough, with thousands of sensors used in a smart house, several megabytes of memory will be wasted by the duplicate events. Also the window defined in a query cannot be reused for any other purpose even inside the same query. To overcome these problems, Event Window is introduced as a global window which can be accessed from any queries any number of times.

The Siddhi queries and the architecture discussed in this article are presented according to the Siddhi version 3.1.1.

Read More

Complex Event Processing - An Introduction

Today almost all the big brothers in the software industry are behind big data and data analytics. Not only the large companies, even small scale companies need data processing in order to track and lead their business. Complex Event Processing(CEP) is one of the techniques being used to analyse streams of events for interested events or patterns. This article explains the big picture of complex event processing in a nutshell using a simple example.


As the name suggests Complex Event Processing is mainly about processing events using some predefined rules. Mainly they are used to derive complex events by aggrgating and processing stream of simple events. For example, identifying that you are reading this blog right now is an easy task for your computer since the browser knows the site which is currently being opened on your computer. However, some events cannot be detected as simple as the above example. For example, how could a supermarket send coupons closed to a teen girl’s delivery date while even her father didn’t know that she was pregnant? (Read the incredible story here: ‘How Target Figured Out A Teen Girl Was Pregnant Before Her Father Did’).

Let’s say our problem is identifying the pregnant customers of a supermarket so that the supermarket can send  coupons for baby clothes and cribs. Assume that according to experts report, if a customer bought cocoa-butter lotion, a purse large enough to double as a diaper bag and ZMA supplements within 7 days, the customer is pregnant (or he/she has a pregnant relation). Using this domain knowledge, we can define the rule to identify the pregnant customers. However, in a supermarket with thousands of customers per day, it is hard to search for such patterns manually using a rule.

Complex Event Processor is a tool to process stream of events automatically as they arrive. Compared to database management systems, database engines store the data and pass the query to process on those data. In contrast, CEPs store the query and pass the data against it and extract the necessary information. There are several CEPs available and this article uses WSO2 CEP which is an open source Java based complex event processor.

WSO2 CEP is recommended to be used as a cluster of nodes for an enterprise level requirement. However, in this article, we use the core of WSO2 CEP known as Siddhi which can be used as a Java library.

Step 1:
Create a new Maven project in Eclipse using the following information.
Group Id: com.javahelps
Artifact Id: siddhidemo

Step 2:
Open the pom.xml and add the following repository. This repository is required to download the latest Siddhi library.
<repositories>
    <repository>
        <id>wso2.releases</id>
        <name>WSO2 internal Repository</name>
        <url>http://maven.wso2.org/nexus/content/repositories/releases/</url>
        <releases>
            <enabled>true</enabled>
            <updatePolicy>daily</updatePolicy>
            <checksumPolicy>ignore</checksumPolicy>
        </releases>
    </repository>
</repositories>

Step 3:
Add the following dependencies. (Java version is optional)
<properties>
    <siddhi.version>3.1.0</siddhi.version>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
</properties>

<dependencies>
    <!--Siddhi -->
    <dependency>
        <groupId>org.wso2.siddhi</groupId>
        <artifactId>siddhi-query-api</artifactId>
        <version>${siddhi.version}</version>
    </dependency>
    <dependency>
        <groupId>org.wso2.siddhi</groupId>
        <artifactId>siddhi-core</artifactId>
        <version>${siddhi.version}</version>
    </dependency>
    <dependency>
        <groupId>org.wso2.siddhi</groupId>
        <artifactId>siddhi-query-compiler</artifactId>
        <version>${siddhi.version}</version>
    </dependency>
</dependencies>

After modification, the pom.xml must look like this:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.javahelps</groupId>
    <artifactId>siddhidemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <repositories>
        <repository>
            <id>wso2.releases</id>
            <name>WSO2 internal Repository</name>
            <url>http://maven.wso2.org/nexus/content/repositories/releases/</url>
            <releases>
                <enabled>true</enabled>
                <updatePolicy>daily</updatePolicy>
                <checksumPolicy>ignore</checksumPolicy>
            </releases>
        </repository>
    </repositories>

    <properties>
        <siddhi.version>3.1.0</siddhi.version>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
    </properties>

    <dependencies>
        <!--Siddhi -->
        <dependency>
            <groupId>org.wso2.siddhi</groupId>
            <artifactId>siddhi-query-api</artifactId>
            <version>${siddhi.version}</version>
        </dependency>
        <dependency>
            <groupId>org.wso2.siddhi</groupId>
            <artifactId>siddhi-core</artifactId>
            <version>${siddhi.version}</version>
        </dependency>
        <dependency>
            <groupId>org.wso2.siddhi</groupId>
            <artifactId>siddhi-query-compiler</artifactId>
            <version>${siddhi.version}</version>
        </dependency>
    </dependencies>
</project>

Step 4:
Create a new package com.javahelps.siddhidemo in src/main/java folder.

Step 5:
Create a new class named Main.java with the main method.

Step 6:
Create a SiddhiManager instance which is used to create an execution plan.
package com.javahelps.siddhidemo;

import org.wso2.siddhi.core.SiddhiManager;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        SiddhiManager siddhiManager = new SiddhiManager();
    }
}

Step 7:
Define a stream as shown below. Here stream is used to define the properties of the input event.
package com.javahelps.siddhidemo;

import org.wso2.siddhi.core.SiddhiManager;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        SiddhiManager siddhiManager = new SiddhiManager();

        String streams = "define stream purchaseStream (customerName string, item string, timestamp long); ";
    }
}
The above definition says, all the events passed to the purchaseStream have the properties customerName and item which are String and timestamp of purchase in long.

Step 8:
The most important step is creating the query.
Here is my logic:
  1. Get all the streams and partition them based on the customer name because there can be more customers and we need to process their data individually.
  2. From every partitions, filter the purchases of interested items.
  3. Again break the events into subsets where each set contains only purchases happened in 7 days interval. For example, if Alice purchased Cocoa-Butter Lotion on Monday, Biscuit on Saturday and Beer on next Tuesday, the  Cocoa-Butter Lotion and Biscuit purchases must be in one subset and Beer must be in another subset.
  4. From each subset of events, take the count of unique items. Count of unique items can range from 1 to 3 since we have already filtered the stream to allow purchases of three items only.
  5. Those who have purchased all three products are pregnant with 100% confidence. Those who have  bought only 2 items are pregnant with 66.67% confidence. Those who have purchased only one product are pregnant with 33.33% confidence.
The Siddhi query for above logic is given below:
partition with (customerName of purchaseStream)
begin
    from purchaseStream[item == 'Cocoa-Butter Lotion' OR item == 'Purse-XL' OR item == 'ZMA']#window.uniqueExternalTimeBatch(item, timestamp, 500 milliseconds)
    select customerName, convert(count(item), 'double') / 3.0 * 100.0 as noOfPurchases insert into possiblePregnant;
end;

1. The input stream is partitioned by customerName.

2. The partitioned stream is filtered to allow only Cocoa-Butter Lotion, Purse-XL and ZMA.

3. Siddhi offers uniqueExternalTimeBatch which can be used to get unique time framed subset of events. The interval of 500 milliseconds is used instead of 7 days for quick response.

4. Select the customerName and count of items from each subset and insert the possible pregnant customers with the level of confidence into the output stream.

Step 9:
Add the stream definition and the query to the Siddhi manager and create the ExecutionPlanRuntime.
package com.javahelps.siddhidemo;

import org.wso2.siddhi.core.ExecutionPlanRuntime;
import org.wso2.siddhi.core.SiddhiManager;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        SiddhiManager siddhiManager = new SiddhiManager();

        String streams = "define stream purchaseStream (customerName string, item string, timestamp long); ";
        String query = "partition with (customerName of purchaseStream) " +
                        "begin " +
                        "from purchaseStream[item == 'Cocoa-Butter Lotion' OR item == 'Purse-XL' OR item == 'ZMA']#window.uniqueExternalTimeBatch(item, timestamp, 500 milliseconds) " +
                        "select customerName, convert(count(item), 'double') / 3.0 * 100.0 as noOfPurchases insert into possiblePregnant; " +
                        "end ";

        // Create ExecutionPlanRuntime using stream definition and query
        ExecutionPlanRuntime executionPlanRuntime = siddhiManager.createExecutionPlanRuntime(streams + query);
    }
}

Step 10:
Create two static arrays one for Customers and the other for Products and a static Random class and add a new method to generate input events.
package com.javahelps.siddhidemo;

import java.util.Random;

import org.wso2.siddhi.core.ExecutionPlanRuntime;
import org.wso2.siddhi.core.SiddhiManager;

public class Main {
    private static final String[] CUSTOMERS = { "Alice", "Barby", "Carol", "Diana" };
    private static final String[] ITEMS = { "Cocoa-Butter Lotion", "Purse-XL", "Purse-L", "Beer", "Biscuit",
            "Chocolate", "ZMA" };
    private static final Random RANDOM = new Random();

    public static void main(String[] args) throws InterruptedException {
        SiddhiManager siddhiManager = new SiddhiManager();

        String streams = "define stream purchaseStream (customerName string, item string, timestamp long); ";
        String query = "partition with (customerName of purchaseStream) " +
                        "begin " +
                        "from purchaseStream[item == 'Cocoa-Butter Lotion' OR item == 'Purse-XL' OR item == 'ZMA']#window.uniqueExternalTimeBatch(item, timestamp, 500 milliseconds) " +
                        "select customerName, convert(count(item), 'double') / 3.0 * 100.0 as noOfPurchases insert into possiblePregnant; " +
                        "end ";

        // Create ExecutionPlanRuntime using stream definition and query
        ExecutionPlanRuntime executionPlanRuntime = siddhiManager.createExecutionPlanRuntime(streams + query);
    }

    private static Object[] generateEvent() {
        String name = CUSTOMERS[RANDOM.nextInt(CUSTOMERS.length)];
        String item = ITEMS[RANDOM.nextInt(ITEMS.length)];
        long time = System.currentTimeMillis(); // Current time

        System.out.println(name + " buys " + item);
        Object[] event = new Object[] { name, item, time };
        return event;
    }
}

Step 11:
Add StreamCallback to receive the output events and InputHandler to send events.
package com.javahelps.siddhidemo;

import java.util.Random;

import org.wso2.siddhi.core.ExecutionPlanRuntime;
import org.wso2.siddhi.core.SiddhiManager;
import org.wso2.siddhi.core.event.Event;
import org.wso2.siddhi.core.stream.input.InputHandler;
import org.wso2.siddhi.core.stream.output.StreamCallback;

public class Main {
    private static final String[] CUSTOMERS = { "Alice", "Barby", "Carol", "Diana" };
    private static final String[] ITEMS = { "Cocoa-Butter Lotion", "Purse-XL", "Purse-L", "Beer", "Biscuit",
            "Chocolate", "ZMA" };
    private static final Random RANDOM = new Random();

    public static void main(String[] args) throws InterruptedException {
        SiddhiManager siddhiManager = new SiddhiManager();

        String streams = "define stream purchaseStream (customerName string, item string, timestamp long); ";
        String query = "partition with (customerName of purchaseStream) " +
                        "begin " +
                        "from purchaseStream[item == 'Cocoa-Butter Lotion' OR item == 'Purse-XL' OR item == 'ZMA']#window.uniqueExternalTimeBatch(item, timestamp, 500 milliseconds) " +
                        "select customerName, convert(count(item), 'double') / 3.0 * 100.0 as noOfPurchases insert into possiblePregnant; " +
                        "end ";

        // Create ExecutionPlanRuntime using stream definition and query
        ExecutionPlanRuntime executionPlanRuntime = siddhiManager.createExecutionPlanRuntime(streams + query);
       
        try {
            // Receive the output events
            executionPlanRuntime.addCallback("possiblePregnant", new StreamCallback() {
                @Override
                public void receive(Event[] events) {
                    String output = String.format("\t\t\t%s is pregnant with %.2f%% confidence.", events[0].getData(0),
                            events[0].getData(1));
                    System.out.println(output);
                }
            });

            // Send input events
            InputHandler purchaseStream = executionPlanRuntime.getInputHandler("purchaseStream");
            executionPlanRuntime.start();
            for (int i = 0; i < 1000; i++) {
                Object[] event = generateEvent();
                purchaseStream.send(event);
                Thread.sleep(10); // Delay for 10 milliseconds
            }
        } finally {
            executionPlanRuntime.shutdown();
        }
    }

    private static Object[] generateEvent() {
        String name = CUSTOMERS[RANDOM.nextInt(CUSTOMERS.length)];
        String item = ITEMS[RANDOM.nextInt(ITEMS.length)];
        long time = System.currentTimeMillis(); // Current time

        System.out.println(name + " buys " + item);
        Object[] event = new Object[] { name, item, time };
        return event;
    }

}

Step 12:
Save all the changes and run the application.

The above query is a sample implementation for the given scenario. There can be other ways to achieve the same output using CEP. For more details about Siddhi, visit to the following link: Siddhi Documentation. This example is a simple application of CEP to process stream of events, however CEP can be used in complex scenarios like weather prediction, the stock market trends, fraud detection in bank transaction, etc as well. If you have any questions or suggestions, please comment below.

Find the project @ Git Hub.
Read More

WSO2 Carbon UI Component - Hello World!

In this article, I will show you how to create a WSO2 Carbon UI front end for an existing web service. Since this is the part II of the last article “WSO2 Carbon Server Component - Hello World!”, the UI will be created for the web service developed in part I. However, the same steps can be followed to create a Carbon UI for any SOAP web services.

Prerequisite:

Read More

Goodbye Log4j

After seeing so many students in last four years, I have decided to write this article about the new loggers which are widely being used by the industry. Almost all the university students I have seen are familiar with Log4j 1.x (at least heard about it) but most of them even did not hear about SLF4J and Logback. The purpose of this article is introducing SLF4J and Logback and convincing you towards them. Before getting into the topic, be informed that Log4j 1.x is not being maintained after August 5, 2015 and Ceki Gülcü the developer of Log4j came up with the new tools SLF4J and Logback. Technically, Logback is an enhanced successor of Log4j and performs better than Log4j.

He did a good job, but we have to move forward.
Read More

Apache Axis2 - Hello World! using Eclipse

The previous article Apache Axis2 - Hello World! provides step by step guide to develop a very basic Axis2 Hello World application without using any IDEs. This article helps you to create a simple application in Axis2 using Eclipse IDE.

Prerequisite:
  • Eclipse IDE for Java EE Developers (Follow this link to install Eclipse)
  • Apache Tomcat (Follow this link to install and integrate with Eclipse)
  • Apache Axis2 (Follow this link to install and integrate with Eclipse)

Update (01/05/2017): With the Axis2 library 1.7.4 there are some JSTL related errors in the JSP file. If you get such errors in your project, add the jstl-1.2.jar into the WebContent/lib directories.

Step 1:
Create a new Dynamic Web Project named HelloAxis2 and change the Dynamic web module version to 2.5 because the current version of Axis2 core does not support versions higher than 2.5.


Read More
Apache Axis2 - Hello World!

Apache Axis2 - Hello World!

Apache Axis2 is a SOAP processing engine and its main function is to deliver incoming SOAP messages into target applications, and in this context application is a Web service. This tutorial provides step by step guidance on how to create your first Hello World application.

Prerequisite:
  • Java Development Kit (Follow this link to install on Ubuntu)
  • Apache Axis2 (Follow this link to setup on Ubuntu)

Step 1:
Create a new class HelloService as shown below.
public class HelloService {

    /**
    * This method will be the add operation of the web service.
    */
    public int add(int x, int y) {
        int ans = x + y;
        return ans;
    }

}


Read More

Import Database with Images in Android

The article Import and Use External Database in Android explains, how to distribute an Android application along with the data stored in SQLite database. This tutorial explains, how to store images in such a database and pack it in your application. In other words, we are going to create a database with images from our desktop computer and import it into an Android application.

Step 1:
Create a database "images.db" using your favorite SQLite database application (I use Sqliteman because it allows inserting images into the database. You can use any software or script to insert the images into the database). Create a table 'places' with a two columns 'name' and 'image'. Here the data type of 'name' is TEXT and data type of 'image' is BLOB. Insert the name and image of  some places into the database. In this example, I have inserted the names of the seven wonders of the world along with a compressed (Using TinyPng) picture of them. To download the images used in this project, Click Here.


Read More

Garbage Collection

Garbage collection is one of the major problem, that is being ignored by most of the Java developers. However, knowing the impact of garbage collection will help you to improve your art of coding in performance critical applications. This article explains the necessity of garbage collection and the best practices to follow when you write such applications. Let's start this article with a simple C application.

Copy and paste the following code in a C source file named as application.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    int i;
    for (i = 0; i < 10000; i++) {
        // Allocate the memory
        char *name = malloc(10000000000);
        if (name == 0) {
            printf("ERROR: Out of memory\n");
            return 1;
        }
        // Assign a value and print it
        strcpy(name, "Hello, world!");
        printf("%s\n", name);
    }
    // Pause the application
    getchar();
    return 0;
}
In this code, malloc command allocates a memory location with 10,000,000,000 bytes and the message "Hello World" is stored in that location. It continues for 10,000 times.

Compile the source code.
gcc  application.c

Run the program.
/.a.out

Depending on your system configuration, either you may get Out of memory error or 10,000 "Hello World" messages. In my computer (Ubuntu 64 bit, Intel Core i3 with 8 GB memory), it prints 10,000 messages.

Following screen shot shows the memory acquired by this C application at the end. As you can see, it consumed 77.1 MiB.


Now modify the source code by adding free(name); command after the printf statement. This command is used to free the memory allocated by malloc.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    int i;
    for (i = 0; i < 10000; i++) {
        // Allocate the memory
        char *name = malloc(10000000000);
        if (name == 0) {
            printf("ERROR: Out of memory\n");
            return 1;
        }
        // Assign a value and print it
        strcpy(name, "Hello, world!");
        printf("%s\n", name);
        // Free the memory
        free(name);
    }
    // Pause the application
    getchar();
    return 0;
}
Compile and run the application again.


This time our application consumed just 96.0 KiB. If you increase the number of iterations (in other words, number of garbage memory allocations), you may get Memory out of error. This example clearly shows the impact of garbage objects in memory management. In a language which does not provide automatic garbage collection, you must be aware of what you are doing. If not, your application may throw memory out of error and terminate.

What is garbage?
In computing, garbage is an unwanted or unused memory allocation. In the perspective of C (or any other languages which provide direct memory access), if you allocate a memory and if you do not want to use it anymore, you must free that memory. If not, the unused memory allocation is identified as garbage. In the context of Java, if there is an unreachable object, that is known as garbage (Primitives are not considered as garbage).

In Java, objects are created in the heap and their reference is returned to you. For example take the following code:
public class StudentDemo {
    public static void main(String[] args) {
        Student stu = new Student(100);
    }
}

class Student {
    int index;

    public Student(int index) {
        this.index = index;
    }
}
If you run this code, a Student object with index number 100 will be created in the heap and a reference will be created in the stack as shown below.


Now, if we say stu = null;, the reference will be removed but the actual student object will be there in the memory. This unreachable objects is called garbage.
public class StudentDemo {
    public static void main(String[] args) {
        Student stu = new Student(100);
        stu = null;
    }
}

class Student {
    int index;

    public Student(int index) {
        this.index = index;
    }
}


Reassigning an existing reference also create garbage objects. In the following code, a new Student object is assigned to the existing stu reference. After this statement, the previous Student object (with index number 100) becomes garbage.
public class StudentDemo {
    public static void main(String[] args) {
        Student stu = new Student(100);
        stu = new Student(101);
    }
}

class Student {
    int index;

    public Student(int index) {
        this.index = index;
    }
}


There can be garbage objects with references (but still unreachable). Look at the following code.
public class IslandOfIsolation {
    public static void main(String[] args) {
        // Create the objects
        Node a = new Node(1);
        Node b = new Node(2);
        Node c = new Node(3);

        // Create internal references
        a.next = b;
        b.next = c;
        c.next = a;

        // Remove the references from main method
        a = null;
        b = null;
        c = null;

        // Now there are 3 garbage objects
    }
}

class Node {
    int val;
    Node next;

    public Node(int val) {
        this.val = val;
    }
}
According to this code, there are three nodes with internal references, but still they are unreachable because there is no way to access any of them from the main method. This kind of garbage objects are called island of isolation.

Garbage in Java is an unreachable object; not an object without reference.
How to remove garbage objects?
There is no way for a Java developer to delete garbage objects from the heap. In other words, Java does not provide any similar methods to C's free method in order to clear the memory allocation. This is where Java's automatic garbage collector comes to the stage. Java has a background thread named "Garbage Collector" which runs on demand and remove the garbage objects from the heap.

Even though, the time to clear the memory is under the control of Java Virtual Machine, Java provides two identical methods to send a request for the Java garbage collector to clear the memory.
System.gc();
Runtime.getRuntime().gc();
However, using these methods does not guarantee the execution of garbage collector, because JVM has the right to ignore your request. Therefore, it is not recommended to depend on these methods. According to my experience, I use these methods only when I teach garbage collection to my students.

Best Practices
There are two important rules regarding garbage collection.

Rule 1: Avoid unnecessary garbage objects
Producing more and more garbage leads to the garbage collector to run frequently and it will significantly reduce the performance of your application.

Example 1: String Concatenation
The bad practice:
public class Concatenation {
    public static void main(String[] args) {
        String str = "";
        for(int i = 0; i < 100; i++) {
            // String is an immutable class
            str += i;   // This line creates a new object and the old object becomes garbage
        }
        System.out.println(str);
    }
}

The best practice:
public class Concatenation {
    public static void main(String[] args) {
        StringBuilder builder = new StringBuilder();
        for(int i = 0; i < 100; i++) {
            builder.append(i);
        }
        String str = builder.toString();
        System.out.println(str);
    }
}
Reason: String is an immutable object. Modifying a String object multiple times, generates multiple garbage objects. For more details, visit to: Immutability of String

Example 2: Integer addition
The bad practice:
public class Addition {
    public static void main(String[] args) {
        Integer total = 0;
        for(int i = 0; i < 100; i++) {
            // Integer is an immutable class
            total += i;   // This line creates a new Integer object and the old object becomes garbage
        }
        System.out.println(total);
    }
}

The best practice:
public class Addition {
    public static void main(String[] args) {
        int total = 0;
        for(int i = 0; i < 100; i++) {
            // Primitives are replaced. They never become garbage
            total += i;
        }
        System.out.println(total);
    }
}
Reason: Integer (or any other wrapper class) object is an immutable object. Modifying an Integer (or other wrapper class) object multiple times generates multiple garbage objects. Use primitives instead of wrapper classes as much as possible.

Rule 2: Avoid memory leaks
Memory leak is the situation where some objects escape from garbage collection. It may lead to performance issues or MemoryOutOfError.


More details about Memory leak and other advanced garbage collection concepts will be discussed in another article.
Read More

Contact Form

Name

Email *

Message *