AppMon provides sophisticated means for diagnosing memory leaks and excessive memory consumption by Java and .NET applications. This page describes memory management in Java and .NET in general, shows how to use AppMon to find memory problems and optimize memory performance, and provides an example of memory diagnostics.
Inefficient use of application memory affects key performance indicators of service management:
- Unavailability of application due to crashes.
- Bad response time due to frequent runs of garbage collection.
- High investment costs from inefficient use of hardware resources.
At worst, memory leaks increase memory demand until out-of-memory exceptions and application malfunctions occur.
Memory problem classification
Generally, memory problems can be classified as follows:
- Memory leaks, leading to unavailability due to crashes.
- Heavy memory use, leading to high costs from hardware requirements.
- Heavy garbage collection use, impacting application performance by frequent object instantiations and high numbers of objects.
Causes of memory leaks
A memory leak is an allocation of memory by the application that is not freed again when the memory is not used anymore. The obvious sign of a memory leak is growing memory consumption with constant load on your application. The causes of memory leaks can be categorized as these programming errors:
- Collections and maps: Memory leaks are often caused by collections containing objects that are no longer used.
- Static fields: Objects assigned to static fields of classes are not cleaned up until the application is shut down or the fields are set to null. Static collections and maps constitute special problems.
- Custom data structures: Custom data structures frequently keep back-references to objects, preventing the freeing of intentionally unused objects.
- Cleanup errors: Code does not properly:
- Use statements to release unmanaged resources, such as native code invoked by JNI.
- Unregister listeners.
- Release pooled resources, such as database connections, which can lead to database connection leaks.
- Inappropriate use of sessions in web applications: Objects stored in session variables live for the duration of a user's session. If sessions are not invalidated explicitly, these objects live until the session's timeout. This can prevent releasing objects for minutes to hours, depending on the configured timeout. This is not technically a memory leak, but it results in poor application performance from inefficient memory use.
- Soft-References: This is not a memory leak by itself, but excessive use of Soft-References makes it hard to detect memory leaks. Soft-References can keep the JVM heap full, making it impossible to use simple JVM metrics monitor the used memory assigned to hard references.
- Inappropriate pool sizes: Object pools enable reuse of objects without permanently creating and destroying costly objects. Using pools can restrict the number of objects created for a specific object type. Inappropriate pool sizes may result in the creation of more objects than an application would actually need. Instead of waiting for a pool object to be available, a new one is created.
Monitoring memory behavior is a good start point of memory diagnostics. You can quickly notice when something is wrong, and start the investigation. You can add memory-related measures to one or several Chart dashlets to see their behavior over time. For example, the .NET Agent can gather information about the managed heap. See Agent Mapping advanced settings for more info.
You can also use AppMon incident-based monitoring of memory behavior. With incident-based diagnosis, you analyze memory problems when they occur by defining incidents for memory usage (for example, 80% of maximum memory) that can be combined with corresponding actions to trigger memory snapshots. For Java 6 VMs, AppMon triggers leak analysis snapshots by default if the application runs out of memory.
It is recommended to monitor memory usage for every running JVM or CLR. The following measures can be useful for memory monitoring:
AppMon provides some charts out of the box for monitoring the most important measure regarding memory.
The Host Health dashboard provides a comprehensive overview of host performance, including memory usage.
In the Pre-Production edition, the Memory Analysis dashboard is available, where you can quickly view the memory usage of the Agents connected to a System Profile. To access it, click Start Center > Memory Diagnosis > Analyze Memory Usage.
Memory diagnosis process
Memory diagnosis is a complex and time-consuming task. AppMon supports efficient and effective detection of memory problems and the implementation of company-specific performance tuning processes. You can create memory snapshots for diagnostics either periodically, through periodic Memory snapshot tasks, or automatically on incidents, or manually in the Total Memory or Selective Memory dashlets.
You can get a hands-on experience of memory analysis in the Memory Analysis tutorial using the easyTravel application.
The process of diagnosing a memory leak depends on the environment.
If it is possible to stall the application for a considerable amount of time (about 15 minutes for an 8-GB JVM), you can use leak analysis snapshots, which contain all instances and their references currently in the heap. Due to long application suspension time this process is considered non-production.
See Memory diagnostics - Pre-production for more information.
If you cannot suspend your application, for example if the application is running in a production environment, AppMon provides the means for trending snapshots and selective memory snapshots. Trending snapshots do not contain every instance or references between instances. However, they provide an overview of which instances are growing. You can use this information in conjunction with selective memory snapshots to find where in an application the instances of a growing class are allocated.
See Memory diagnostics - Production for more information.