Debugging RAM: Detect/Fix Memory Leaks in Managed Languages – Heap Deep Dive (Part 2)

In the previous installment, I talked about the Java garbage collector. In this part, I'll discuss the most common memory issue: the memory leak. I focus on managed languages, specifically Java, but I will mention some native code tools which are interesting. A memory leak contributes to heap size, which isn't the most pressing bug in most cases. But when left alone, memory usage can become a problem and, by that point, finding the issue is hard. Unlike a crash dump, where we get a reference to a specific line, a memory leak can remain hidden.

What are the Consequences of Memory Leaks?

Unfortunately, this often means that memory leaks can carry into production and even cause problems to end users. E.g. This recent story about memory leaks hobbling Apples latest M1 computers. Virtual memory effectively means operating systems can carry memory leaks for a very long time. The performance overhead will be noticeable, though.

High-Performance Java Serialization to Different Formats

Java serialization is a popular mechanism where you are able to serialize and deserialize complex object graphs; for example where object A can contain a reference to object B, which in turn has a reference back to object A. The problem is that this rich functionality comes at a performance cost. However, if you do not need to serialize these types of recursive graphs, you can instead use an Open Source solution called Chronicle Wire. It has reduced complexity and uses tree-like structures which makes it very efficient. Moreover, it can be done in a lot of different formats with no need to change the coding. This article covers the basics of serialization and discusses some of the key advantages of Chronicle Wire.

Serialization and Deserialization

Serialization is about encoding java objects into bytes, for example, we have an object. Let’s say our object holds our application state, if we were to shut down our application we would lose the state, we want to first store our application's state to disk, so we serialize our java state object. This will convert the object into bytes, which can be easily stored.  Likewise, If we want to send the data stored in our java object, over the network, we first have to serialize the object, before it can be written to the TCP/IP buffer. Deserialization is the opposite of serialization, where we start with a byte and recreate an object instance. 

The Performance Impact of java.lang.System.getProperty()

‘java.lang.System.getProperty()’ is a common API used by Java developers to read the System properties that are configured during application startup time. i.e. when you pass “-DappName=buggyApp” as your application’s startup JVM argument, the value of the ‘appName’ system property can be read by invoking the ‘java.lang.System.getProperty()’. Example:

Java
 
public static String getAppName() {    
  
    String app = System.getProperty("appName");   
    return app;
}


What Is Microbenchmarking?

Introduction

Optimisation of code is an endless struggle. It is often even hard to produce meaningful metrics using jvm as it is an adaptive virtual machine. The article is

  • a brief introduction to microbenchmarking,
  • why microbenchmark,
  • when to consider it, and finally,
  • pitfalls to avoid

What Is a Microbenchmark

A microbenchmark is an attempt to measure the performance of a small unit of code. The tests are usually in the sub-millisecond range. The tests can help determine how the code is going to behave when released into production. These tests are guide to a better implementation.

Spring, Hibernate, EhCache Recipe

A Simple Scenario explaining the Usage and Performance, when using EhCache (2nd Level Cache of along with Hibernate in a Spring environment. The performance results are taken using mySQL as the Database. 

Though this Example is from Spring 2.5.x and Hibernate 3.x and EhCache 1.4, MySQL 5.0 => The Concepts Demonstrated will Continue to Hold Good for any Version of any Make of Second Level Cache Product with Hibernate (Optionally, Spring) such as Infinispan, Redis, Hazelcast, ...

[Download Sample Code] Please be informed that the size is about 10MB; as i have provided all the dependencies.

In this example, I need to retrieve close to 5,000 records in a single fetch and then cache this information. As usual, setup Spring contexts in your Spring configuration file. I have just one class, which is a Hibernate DAO, HibernateDoctorDAO.java. The dependency injection hierarchy is dataSource sessionFactory hibernateTemplate. hibernateTemplate is then injected into the HibernateDoctorDAO.java at runtime by the Spring Framework.

The Implementations of Each of These Are:
dataSource > org.apache.commons.dbcp.BasicDataSource
sessionFactory > org.springframework.orm.hibernate3.LocalSessionFactoryBean
hibernateTemplate > org.springframework.orm.hibernate3.HibernateTemplate

The results clearly shows the difference in performance with EhCache enabled, even in this simple example:
 
PERFORMANCE COMPARISON (In Seconds)
==============================
QUERY FETCH TIME (INITIAL): 0.599
QUERY FETCH TIME (HIBERNATE CACHE): 0.212
QUERY FETCH TIME (2ND LEVEL CACHE): 0.091
Version Reference > Spring-2.5, Hibernate-3.0, EhCache-1.4, mySQL-5.0
 

Instructions: Unzip the file and start by creating the database. Any mySQL database that is compatible with the MySQL Connector 5.0.8 is fine for this example. You will have to create the database data_explosion (USERNAME: root, PASSWORD: architect.2012) and the table DOCTOR_TABLE. You can use the provided doctor.sql as reference. Then run the java standalone com.sumsoft.spring.orm.hibernate.dataload.JDBCDataLoader to create and load a large number of arbitary records into the DOCTOR_TABLE. You can ignore or remove every invocation that is to PATIENT_TABLE, as this is only additional for this example. Then use spring_hibernate_cache.bat to run the application. Though not tested on UNIX, you may write a script similar to the batch file to run this application. 

AOT Compilation Make Java More Power

I experimented with a previous article to explore about 6000 classes being loaded for a simple hello world spring boot rest application.  Although the Quarkus version seems optimized by reducing the number to 3300+, It is still way too much. In this article, I will introduce how we can use Java AOT compilation to eliminate the dead code in Java and therefore improve the performance dramatically.

The experiment uses Quarkus as a framework.

Project Valhalla: Fast and Furious Java

Performance Improvements of New Inline Types

Project Valhalla is one of the most interesting projects concerning the future of Java and of all JVM. It is still in an experimental state, but in this post, we will look at how to use it and implement a small program to verify possible performance improvements.

Valhalla's aim is to bring a new Inline Types (aka Value Types) that will: "Codes like a class works like an int."

Custom Framework Listeners

In my past articles, I’ve written about using custom listeners as part of getting the desired reporting or making your tests do what you want. I’ve always referred offhandedly to these listeners, never paying them direct attention. I figured it was finally time to actually write a full-fledged post about listeners and some useful tricks.

What Is a Listener?

Most testing frameworks (JUnit, TestNG, Cucumber, Robot…) have what they call a ‘listener.’ This is a class with methods that runs before or after your tests and has hooks into reporting and logging. It works within the framework to identify what passes, what fails, and maybe even why. Sometimes, these also include how and when tests are executed. Understanding how these listeners work can add additional insight into how your tests run. Understanding how these listeners can be modified can allow you greater control over your tests.

How to Tune Garbage Collection in Java

Garbage collection is the mechanism by which the JVM reclaims memory on behalf of the application when it's no longer needed. At a high level, it consists of finding objects that are no longer in use, freeing the memory associated with those objects, and occasionally compacting the heap to prevent memory fragmentation.

The garbage collector performs it's work using one or more threads. But in order to do the job of tracking down object references and moving objects around in memory, it needs to make sure that the application threads are not currently using those objects because if, for example, an application thread is using an object and then the memory location of the object changes due to GC, then bad and unpredictable things could happen. This is why garbage collectors must pause all application threads when performing certain tasks. These pauses are sometimes called Stop-The-World pauses, and the minimization of them is the primary concern of GC tuning, as they can have a huge impact on the performance of a Java application.

Low-Latency Java: Part 1 — Introduction

This is the first article of a multi-part series on low latency programming in Java. At the end of this introductory article, you will have grasped the following concepts:

  • What is latency, and why should I worry about it as a developer?
  • How is latency characterized, and what do percentile numbers mean?
  • What factors contribute to latency?

So, without further ado, let's begin.