Detecting memory leaks in AnyLogic models

Updated: May 21

Often during simulation model building, one comes to a point where you need to optimize your model's performance. Either through improved memory usage or CPU utilization. This can be a near-impossible task through just code review or manual trial and error changes. Luckily, a specific tool is available for Java applications to help you and make life easier.


This is part 1 of a 2 part series where we look at using a profiler to analyze model performance.


In this post, we will look at an example of how to detect memory leaks and improve memory consumption.

gif

Rather watch the 10 min video? Click here


Example


Let's have a look at the following super simple simulation model. We have a super basic simulation model of a system where we have agents arriving into a queue, being serviced and then exiting the system. If an agent waits too long in the system, it leaves the queue prematurely, does not get serviced, and exits the system.

We want to measure the time the agents that do get serviced spend in the system, so we have added a time measure start and time measure end block right before and after the service block for the objects that exit the system prematurely.

This basic service flow simulation can be representative of a number of real-life processes, from call centers, where callers are only willing to wait a certain amount of time for service, or, e.g., a carwash where potential patrons will only wait a few minutes in the queue before deciding rather to skip wash day.


P.S. If you consider yourself and advanced AnyLogic user you should be able to spot the issue in the above model as well as the impact it will have on your model performance. Take a moment and make a prediction and write the outcome of your prediction in the comment section below.

The model is really simple, and we plan to make major improvements to it, adding a significant amount of details and features. But before we do let's give it a quick run for one full year and check the results.


So here goes...

Everything looks good, the model completed the full year in under 9 seconds, and the results look good... but wait, have a look at the memory consumption... 500MB of memory. We have not even begun to add significant detail to the model! How on earth are we going to run the model after we have doubled the number of agents and added tons of statistics and additional logic....



Finding the memory leak


gif

Luckily, optimizing java application performance has been around for a long time. We don't need to rely on our own intuition or trial and error to try and optimize our simulation model.


There are a number of commercial tools available for Java application profiling, one I prefer is from eJ Technologies called Jprofiler and you can read up on it here. However, if you are starting out you probably don't want to spend money on a tool that you don't know how to use. Luckily, free applications like Visual VM are available that you can download for Mac and Windows here.

FYI: Monitoring an application using VisualVM Monitor view

  • CPU Usage: This charts plots the CPU usage over time and is used to indicate when model requirements are overloading the CPU

  • Heap: The Heap graph displays the total heap size and how much of the heap is currently used. Heap is similar to memory

  • Classes: The Classes graph displays an overview of the total number of loaded classes and shared classes.

  • Threads: The Threads graph displays an overview of the number of live and daemon threads in the application's JVM. You can use VisualVM to take a thread dump if you want to capture and view exact data on application threads at a specific point in time.



What is Visual VM

  • VisualVM is a visual tool integrating several command‐line JDK tools and lightweight profiling capabilities. Designed for both production and development time use, it further enhances the capability of monitoring and performance analysis for the Java SE platform.

  • Application Developer enables you to monitor, profile, take thread dumps and browse heap dumps.

  • The main window of VisualVM opens when you launch the application. By default, the Applications window is displayed in the left pane of the main window. The Applications window enables you to quickly see the Java applications running on local and remote JVMs.


Using Visual VM to detect memory leaks


Use the steps below to conduct a memory analysis on your application or watch the video here for step by step instructions


1) Run your model up to the point where the memory consumption is a problem and then pause your model. In our case, this is at the model end

2) Open the Visual VM application.

3) In the left pane, you will see 2 applications linked to your model. The AnyLogic database as well as the model itself.


4) Double click the application associated with your model, and select the monitor tab in the right pane

As you can see from the overview statistics we are using zero CPU, which makes sense as the model finished running. Yet we are consuming almost all of the 500 MB available for memory.

FYI: Monitoring an application using VisualVM Monitor view

  • CPU Usage: This chart plots the CPU usage over time and is used to indicate when model requirements are overloading the CPU

  • Heap: The Heap graph displays the total heap size and how much of the heap is currently used. Heap is similar to memory

  • Classes: The Classes graph displays an overview of the total number of loaded classes and shared classes.

  • Threads: The Threads graph displays an overview of the number of live and daemon threads in the application's JVM. You can use VisualVM to take a thread dump if you want to capture and view exact data on application threads at a specific point in time.


5) Navigate to the Sampler page, select memory in the sample section and pause the profiler and select the Heap Dump




FYI: Memory Profiling

In the memory profiling mode VisualVM displays the total number of objects allocated by each class loaded by the application. For each class loaded in the Java Virtual Machine (JVM), the profiling results display the size and number of objects allocated since the profiling session started. The results are automatically updated as new objects are allocated and as new classes are loaded. The bytes allocated are also displayed as a graph representing the percentage of bytes as well as the total number of bytes allocated by each class


6) On the heap dump page, navigate to the Objects view in order to analyze the heap dump