#11 Garbage Collection Tuning Guide for JDK 11
Modern Best Practices for Testing in Java. JDK 14, Micronaut, Google Cloud Run and Lambda Functions. Random Numbers.
Welcome to the eleventh Dukesletter edition!
This week we have a lot of updates in different JEPs:
JEP 360: If you develop with Scala, Sealed Classes term will be familiar for you, but it is new for Java language. In JDK 15 we will have a preview version.
JEP 373: To simplify existing network code and support changes for Project Loom, DatagramSocket API is being reimplemented for JDK 15
JEP 375: Pattern Matching for instanceof will not have a final release, and will continue improving as Preview Feature.
JEP 384: Records specification is evolving and we will have a Second Preview in JDK 15. We need to wait for a final version.
Garbage Collection Tuning Guide for JDK 11
Usually, we don’t need to tune the Garbage Collector and we leave the default values. This is because the JDK Team does a very good job and normally the default configuration gives us a good performance and we don’t need to review it.
But sometimes good enough is not valid and we must squeeze all resources of our servers, or simply because our application behavior or usage pattern is not one of the cases covered by the default configuration.
In these cases, we can not throw more hardware to our Data Center. Some SLAs require certain response time in the 99th percentile, and the main enemy in these types of metrics is the Garbage Collector. A little tuning of the GC will save us a lot of time and money.
Oracle has published a guide with an introduction to all available Garbage Collectors in JDK 11, and for each one, gives a small description of their parameters and configuration tips: HotSpot Virtual Machine Garbage Collection Tuning Guide
The guide is a good starting point to understand key concepts, and move on to more in-depth documentation.
Modern Best Practices for Testing in Java
Everybody knows that writing tests are a good practice, and we all write a lot of tests. But writing good tests is difficult, both unitary and integration ones. Write them before or after creating your code, but write it!
Philipp Hauer has written an article with best practices. Some are generic to any stack and others are concrete to some Java tool (Junit 5, AssertJ or TestContainers): Modern Best Practices for Testing in Java.
I recommend you revisit the article periodically, because you can always apply some advice that you have forgotten.
If you read the article you can see that Philipp doesn’t mention mock frameworks (just for remote services). Why? because if you follow these best practices you will not need it. Using a lot of mocks in your tests is a bad smell.
The article links to it at some point, but after reading the post, continue with “Focus on Integration Tests Instead of Mock-Based Tests“ to understand how to avoid mocking everything and their advantages.
JDK 14, Micronaut, Google Cloud Run and Lambda Functions
The latest trend is Serverless technologies, JDK 14 has just arrived and Micronaut framework is gaining traction. Can we mix them to create an application?
Guillaume Laforge has written an article explaining how to create a Micronaut application with Java 14 and deploy it to Google Cloud Run, their Serverless service for containers: Start the fun with Java 14 and Micronaut inside serverless Containers on Cloud Run.
Don't miss the chance to try out Micronaut framework, its team is doing a great job, and for me is the best option to create microservices or applications of all sizes.
This article is a good excuse to give my opinion about the trend of Serverless Lambda Functions:
What happens when a set of Lambda Functions needs to be deployed at once? They become a complete application, because all Functions have the same lifecycle.
Usually, a web application is a set of endpoints, and if you follow the best practices for cloud applications, you make it stateless. Then, which is the difference between these sets of Lambda Functions and a REST stateless server? None.
Given the serverless nature of Cloud Run, for me is a perfect tool for developing these small functions packaged together in the same artifact. Thanks to Micronaut you can have a very fast warm-up time and with a very low memory footprint (even more if you use GraalVM native images).
Because you deploy a simple docker image in Cloud Run, if at some point the serverless model doesn’t apply to your needs, or the pricing model of serverless service is worst than having dedicated instances, you can migrate your service to another schema without changing your deployable artifact!
What do you think?