我有一个Java应用程序,似乎从OS分配了越来越多的内存(但是堆大小根本没有增长!)这是一个与PLC通信的应用程序,因此需要相当多的CPU。
为了测试written,我已经编写了此程序,以确保问题不在某些库中:
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
这意味着应用程序在3个线程中每100ms分配和释放10MB。
现在我遇到了Native Memory Tracking
,它为Internal
提供了此输出
- Internal (reserved=367356KB, committed=367356KB)
(malloc=367324KB #3131147)
(mmap: reserved=32KB, committed=32KB)
开始时它需要大约15MB
,现在几乎需要400MB
我刚遇到this documentation,但这并不能真正帮助我。有什么线索可以防止Java从OS分配越来越多的内存吗?
编辑:分配和释放内存的速度越快,操作系统中的内存增长越快
答案 0 :(得分:1)
我跑了你的片段。
这是在VisualVM中的外观(JDK 11,标准设置):
我在任务管理器(Windows)中检查了资源使用情况。是恒定的。
因此,我在Linux上进行了检查。不得不安装htop
并升级JDK,但我认为没有什么区别。这是程序运行5分钟左右后的htop
输出。 VIRT和RES值保持不变,总内存消耗保持相似。
再过5分钟。分辨率更改为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)