[JAVA] How to use VisualVM

Introduction

VisualVM is a tool that allows you to check Java memory usage. It is used to check if there is a tendency for memory leaks when conducting continuous load tests. I think it's not a new tool, but I think it's still an active tool, and some people don't know much about it, so I used a sample program that tends to leak memory and used it easily (as far as I know). In).

Sample program

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class MemoryLeak {

	private static class SampleClassA {
		private final List<byte[]> list = new ArrayList<>();

		private void malloc() {
			list.add(new byte[1024]);
		}

		private void clear() {
			list.clear();
		}
	}

	private static class SampleClassB {
		private final List<byte[]> list = new ArrayList<>();

		private void malloc() {
			list.add(new byte[1024]);
		}

		private void clear() {
			;
		}
	}

	public static void main(String[] args) throws Exception {
		SampleClassA sampleA = new SampleClassA();
		SampleClassB sampleB = new SampleClassB();

		while(true) {
			sampleA.malloc();
			sampleB.malloc();
			sampleA.clear();
			sampleB.clear();

			TimeUnit.MILLISECONDS.sleep(100);
		}
	}

}

SampleClass A and Sample Class B each allocate and release 1kB of memory every 100 milliseconds. It looks almost the same, but SampleClass B doesn't actually free up memory.

How to use

Let's test it easily using the above sample program.

1. Start VisualVM

to start. In this example, we use VisualVM in Pleiades of Eclipse (in Windows, you should be able to start it with java / 8 / bin / jvisualvm.exe).

2. Run the program you want to test

This time, execute the above sample program from Eclipse. When you run it, the running program will appear in VisualVM as shown below (it may not appear if you download VisualVM separately from Eclipse). image.png Click this to see the current CPU usage and memory usage as shown below. image.png

3. Record the state at the start of the test

Record it later for comparison with the state at the start of the test. For the time being, after executing GC from the monitoring tab, take a screenshot and record the current memory usage (blue part is the current memory usage). Also, if you press the heap dump button from the upper right of the monitoring tab, you can get the class information currently being read as shown below. image.png

4. Leave for a while

Even if the memory usage seems to be increasing temporarily, it seems that the increase may stop in the middle, so leave it for a certain period of time. In the old company, it was monitored by leaving it for about a week, at least 3 days, but it depends on how long the monitoring period should actually be.

5. Compare with post-test results

Since it is troublesome, it will be completed in about 2 hours and compared with the result before the test. image.png The memory usage after executing GC is about 80MB. Before the test, it was about 10MB, so you can see that it is rising. By acquiring a new heap dump, you can compare it with the previous heap dump. If you get a heap dump as before and select Compare with another heap dump from the upper right of the class tab, you can see what kind of instance is increasing like the following. In this case, byte [] is increasing. image.png You can also find out where the instance is referenced from here. Double-click byte [] in the cluster tab, click the appropriate one from the instance on the left, and then open the reference in the lower right. At least one of the byte [] instances is referenced from SampleClass B. You can see (see the type part). image.png In production, various instances are referenced from various places, but in this case, even if you open the references of other instances, you can see that they are mostly referenced from SampleClass B.

in conclusion

Recommended Posts

How to use VisualVM
How to use Map
How to use rbenv
How to use letter_opener_web
How to use with_option
How to use fields_for
How to use java.util.logging
How to use map
How to use collection_select
How to use Twitter4J
How to use active_hash! !!
How to use MapStruct
How to use hidden_field_tag
How to use TreeSet
[How to use label]
How to use identity
How to use hashes
How to use JUnit 5
How to use Dozer.mapper
How to use Gradle
How to use java.util.stream.Collector
How to use Map
[Java] How to use Map
How to use Chain API
How to use java Optional
How to use JUnit (beginner)
How to use Ruby return
[Rails] How to use enum
How to use @Builder (Lombok)
[Swift] How to use UserDefaults
How to use java class
How to use Swift UIScrollView
How to use Big Decimal
[Java] How to use Optional ②
[Java] How to use removeAll ()
How to use String [] args
[Java] How to use string.format
How to use rails join
How to use Java Map
How to use dependent :: destroy
How to use Eclipse Debug_Shell
How to use Apache POI
How to use Java variables
[Rails] How to use authenticate_user!
How to use GC Viewer
[Java] How to use Optional ①
How to use Lombok now
[Creating] How to use JUnit
[Rails] How to use Scope
How to use the link_to method
[Rails] How to use gem "devise"
How to use Lombok in Spring
How to use StringBurrer and Arrays.toString.
How to use Java HttpClient (Get)
How to use scope (JSP & Servlet)
How to use the include? method
[Rails] How to use devise (Note)
How to use the form_with method
[Rails] How to use flash messages
How to use EventBus3 and ThreadMode
How to use Spring Data JDBC