Is Files.getLastModifiedTime () a memory leak?

I ran into an error when one of our server applications was using more and more memory every second, and I was able to filter out a short example that still shows this behavior:

public class TestGetLastModifiedTime { private static final Path PATH = Paths.get("D:\\test.txt"); private static final ScheduledExecutorService SCHEDULER = Executors.newScheduledThreadPool(1); public static void main(String[] args) { SCHEDULER.scheduleAtFixedRate(() -> getLastModifiedTime(), 0, 1, TimeUnit.SECONDS); } private static void getLastModifiedTime() { try { FileTime lastModifiedTime = Files.getLastModifiedTime(PATH); } catch (IOException ex) { throw new UncheckedIOException(ex); } } } 

Works on Windows 8.1 and Java 8u20.

Through VisualVM, I noticed that the maximum heap size does not grow and that the heap continues to grow. At the same time, I observe in the Windows task manager that the called java.exe process continues to use (reserve) more memory every second.

The interesting part is that when I run GC from VisualVM, all the heap memory used gets reset to almost zero, and the used memory of the java.exe process does not decrease, as expected, since it is considered to be backup.

However , after the GC was done, memory usage is still increasing every second, and now, of course, there is enough free space for the heap.

Metaspasia is also not affected.

For me, it really smells and looks like the JVM has a memory leak.

Can someone help me and explain what is going on here?

+7
java java-8 memory-leaks jvm
source share
1 answer

I do not consider this a leak for the following reasons:

  • You note that when you run gc , memory usage reverts to default. This is not how the leak works. When there is a leak, these objects are reachable and even after re-collecting garbage, the heap size does not decrease significantly.
  • Heap growth does not mean leakage. It may also mean that too many objects are being created. This is normal and beautiful. And in your case, when it is called in a loop. Yes
  • On my machine, java -Xmx20M TestGetLastModifiedTime worked fine for 10 minutes before I killed the process. If a leak occurs, it will eventually throw an OutOfMemoryError or have too many repeating gc
  • If you observe in visualvm, memory consumption jumped between 2mb and 2.8mb. Which is hardly suspicious of a leak. Moreover, a lot of memory consumption is expected since Files.getLastModifiedTime(PATH) , ExecutorService internally will create small utility objects here and there. So it looks great to me.

Behavior on my machine:

enter image description here

From all that has been said, Windows Manager shows higher heap usage. It is quite possible. If necessary, the JVM can reserve a seat. Perhaps this will be normal with increased heap usage than with gc . Which makes perfect sense (why should you be ascetic when you are rich?).

This is why tools such as monitoring Windows Manager / free -m , etc., do not give due attention to what is happening inside the country. To get quick grades, you might want to do:

 jstat -gccapacity 9043 | tail -n 1 | awk '{ print $4, $5, $6, $10 }' | python -c "import sys; nums = [x.split(' ') for x in sys.stdin.readlines()]; print(str(sum([float(x) for x in nums[0]]) / 1024.0) + ' mb');" # change the pid from 9043 to your jvm process id. #jvm process id can be known by running `jcmd` command (available as part of jdk) 

What else gives you a higher score than free -m / Windows Manager

+7
source share

All Articles