Java进程使用恒定堆大小,在操作系统中分配越来越多的内存。
Java进程使用恒定堆大小,在操作系统中分配越来越多的内存。
我有一个Java应用程序,似乎从操作系统(但堆大小根本没有增长!)分配了越来越多的内存。它是一个与PLC通信的应用程序,因此需要相当多的CPU。
为了测试目的,我编写了这个程序,以确保问题不在某个库中:
public static void main(String[] args) { Random rand= new Random(); if (args[0].equals("auto")) { for(int i = 0; i< Integer.valueOf(args[2]);i++) { new Thread(new Runnable() { @Override public void run() { List<byte[]> threaddata = new ArrayList<>(); while(true) { byte[] arr = new byte[Integer.valueOf(args[3])]; rand.nextBytes(arr); threaddata.add(arr); Thread.sleep(Long.valueOf(args[1])); threaddata.clear(); Thread.sleep(Long.valueOf(args[1])); } } }).start(); } }
我像这样启动了应用程序
java -XX:NativeMemoryTracking=detail -Xmx1G -XX:+UseG1GC -XX:G1PeriodicGCInterval=10000 -XX:G1HeapWastePercent=10 -jar gctest.jar auto 100 3 10000000
这意味着该应用程序每100毫秒在3个线程中分配和释放10MB。
现在我遇到了“本机内存跟踪”,它为我提供了有关“内部”的输出:
- Internal (reserved=367356KB, committed=367356KB) (malloc=367324KB #3131147) (mmap: reserved=32KB, committed=32KB)
起初它大约需要15MB,现在它几乎需要400MB。
我刚刚遇到了这个文档,但它并没有真正帮助我。有什么线索可以防止Java从操作系统分配更多的内存吗?
编辑:我分配和释放内存的速度越快,操作系统中的内存就越快增长。
admin 更改状态以发布 2023年5月22日
我运行了你的代码片段。
这是在VisualVM(JDK 11,标准设置)中的效果:
我在任务管理器(Windows)中查看了资源使用情况。它是一直保持不变的。
所以,我在Linux上进行了检查。我必须安装htop
并升级JDK,但我在那里看不到任何区别。在运行程序5分钟左右后,下面是htop
的输出。VIRT和RES值保持不变,总内存消耗保持相似。
再过5分钟后,这里的Res变为了119M,但我认为这没有什么可担心的。
从本地内存跟踪中,相隔5分钟:
[root@Ukyo 130 /download]# while sleep 300; do jcmd 16920 VM.native_memory |grep Internal -A 3; done Internal (reserved=605KB, committed=605KB) (malloc=565KB #1151) (mmap: reserved=40KB, committed=40KB) Internal (reserved=605KB, committed=605KB) (malloc=565KB #1151) (mmap: reserved=40KB, committed=40KB)