当前位置: 首页 > 知识库问答 >
问题:

Java进程具有恒定的堆大小,在操作系统中分配越来越多的内存

谭卜鹰
2023-03-14

我有一个java应用程序,它似乎从操作系统分配了越来越多的内存(但堆大小根本没有增长!)它是一个与PLC通信的应用程序,因此需要相当多的CPU。

为了测试porpuse,我编写了这个程序,以确保问题不在某些库中:

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。

现在我遇到了本机内存跟踪,它为我提供了内部的输出

-                  Internal (reserved=367356KB, committed=367356KB)
                        (malloc=367324KB #3131147)
                        (mmap: reserved=32KB, committed=32KB)

起初它需要大约15MB,现在几乎需要400MB

我刚看到这个文档,但它对我一点帮助都没有。有什么线索可以阻止java从操作系统中分配越来越多的内存吗?

编辑:我分配和释放内存越快,操作系统中的内存增长越快

共有1个答案

何海
2023-03-14

我查了你的片段。

这是它在VisualVM(JDK 11,标准设置)中的外观:

我检查了任务管理器(Windows)中的资源使用情况。它是恒定的。

所以,我检查了Linux。必须安装htop,并升级JDK,但我看没有区别。这是运行程序5分钟后的htop输出。VIRT和RES值保持不变,总内存消耗保持相似。

再过5分钟就到了。Res改为119米,但我认为这没什么好担心的。

从本机内存跟踪开始,相隔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)
 类似资料:
  • 前面提到多进程的并行可以提高并发度,那么进程是越多越好?一般遇到这种问题都回答不是,事实上,很多大型项目都不会同时开太多进程。 下面以支持100K并发量的Nginx服务器为例。 举个例子: Nginx Nginx是一个高性能、高并发的Web服务器,也就是说它可以同时处理超过10万个HTTP请求,而它建议的启动的进程数不要超过CPU个数,为什么呢? 我们首先要知道Nginx是Master-worke

  • 主要内容:前言,1、是否依赖Java系统自身内存处理数据?,2、依赖Java系统自身内存有什么缺陷,3、优化为依赖OS Cache而不是JVM,4、老司机经验之谈:,5、正确的做法:前言 这篇文章,给大家聊一个生产环境的实践经验:线上系统部署的时候,JVM堆内存大小是越大越好吗? 先说明白一个前提,本文主要讨论的是Kafka和Elasticsearch两种分布式系统的线上部署情况,不是普通的Java应用系统。 1、是否依赖Java系统自身内存处理数据? 先说明一点,不管是我们自己开发的Java应

  • 问题内容: 主管的指示:“我要避免在其中添加任何逻辑models.py。从现在开始,让我们将其用作访问数据库的类,并将所有逻辑保留在使用模型类或包装它们的外部类中。” 我觉得这是错误的方法。我觉得将逻辑排除在模型之外只是为了减小文件大小是一个坏主意。如果逻辑在模型中是最好的,那么无论文件大小如何,它实际上都是应该去的地方。 那么有没有一种简单的方法可以只使用include?用PHP讲,我想向主管建

  • 问题内容: 有什么办法可以通过Java获取操作系统上的总内存量?使用 返回JVM允许的内存,而不是操作系统的内存。有没有人有办法(从Java代码)获取此信息? 问题答案: 返回JVM的可用RAM大小(受32位限制),而不是堆大小。

  • 我们的一个sap系统(PI ABAP JAVA stack)出现了性能问题。为机器配置的整个64GB都被占用了(还有8个内核)。每个人都在怀疑java部分,但我认为不同。 重启内存不足错误的java服务器节点。查看hprof文件,我发现当为服务器节点配置3GB(-Xms和Xmx)堆时,它们的大小只有1.2G(3个服务器节点的平均大小)。这一观察导致以下疑问。 我读到过,当Xms和Xmx设置为相同的

  • 我正在使用Firebase来保存我的数据。我试图在活动中分离Firebase方法和我的方法。例如,我已经创建了一个名为"Firebase method odsHelper"的类,在那里我想编写所有的Firebase方法。例如,"getAllUser"方法应返回列表中的所有用户。我唯一的问题是它不起作用。 我不知道我做错了什么,所以如果你们能帮我。 碎片 FirebaseMethodHelper类