Memory Leak Due To Improper Exception Handling

In this post, let’s discuss an interesting memory problem we confronted in the production environment and how we went about solving it. This application would take traffic for a few hours after that it would become unresponsive. It wasn’t clear what was causing the unresponsiveness in the application.

Technology Stack

This application was running on AWS cloud in r5a.2xlarge EC2 instances. It was a Java application running on an Apache Tomcat server using the Spring framework. It was also using other AWS services like S3 and Elastic Beanstalk. This application had a large heap size (i.e. -Xmx): 48GB.

Exception Handling in Java: Contingencies vs. Faults

Introduction

Since the invention of the Java language, there has been a long-standing debate about checked versus unchecked/runtime exceptions. Some people argue that checked exceptions promote a better design. Others feel that checked exceptions get in the way, especially as systems mature and refactor over time, and therefore unchecked exceptions are better. The Effective Java Exceptions article settles this debate once and for all: both checked and unchecked exceptions are acceptable, and each has its purpose within an application. I highly recommend reading that article. I will refer back to its concepts and terminology going forward.

Exception Handling

Exception handling is an important part of the design and architecture of an application. It represents alternate flows or scenarios other than the "happy path" flow through an application. Generally, business requirements only tell you how the application should behave when everything happens as expected. They rarely describe what to do when something goes wrong.

Avoiding NullPointerException

surprise

The terrible NullPointerException (NPE in short) is the most frequent Java exception occurring in production, according to a 2016 study. In this article, we'll explore the main techniques to fight it: the self-validating model and the Optional wrapper.

Self-Validating Model

Imagine a business rule: every Customer has to have a birth date set. There are a number of ways to implement this constraint: validating the user data on the create and update use-cases, enforcing it via NOT NULL database constraint and/or implementing the null-check right in the constructor of the Customer entity. In this article, we'll explore the last one.