是否有一个命令行工具(Linux)来检查Java应用程序的堆大小(和使用的内存)?
我试过jmap.但它提供了信息.关于内部记忆区域,如Eden/PermGen等,这对我没用.
我正在寻找类似的东西:
最大内存:1GB
最小内存:256 MB
堆内存:700 MB已
用内存:460 MB
就这样.我知道我可以在JConsole等中看到这个,但我需要一个命令行工具(不能启用JMX等)
任何这样的工具/命令?
这个HTOP输出中的VIRT列是什么意思?它呈红色并加粗.
我正在运行一个包含4个节点的弹性搜索集群并索引大量数据.
它始终显示绿色健康.
这是一款带有4GB RAM和2个CPU的 DigitalOcean液滴.我正在将heapsize设置为2gb (-Xms和-Xmx).
这是RAM内存的开销吗?
1 [||||| 9.4%] Tasks: 26, 122 thr; 2 running
2 [||| 4.3%] Load average: 0.25 0.47 0.65
Mem[||||||||||||||||||||||||||||||2592/3954MB] Uptime: 2 days, 01:05:57
Swp[ 0/0MB]
PID USER PRI NI VIRT RES SHR S CPU% MEM% TIME+ Command
9629 root 20 0 16.2G 2516M 97360 S 12.0 63.6 27h02:30 /usr/bin/java -Xms256m -Xmx1g -Xss256k -
21564 root 20 0 16.2G 2516M 97360 S 4.0 63.6 1:12.17 /usr/bin/java -Xms256m -Xmx1g …Run Code Online (Sandbox Code Playgroud) 我正在对tomcat服务器执行负载测试.服务器具有10G物理内存和2G交换空间.堆大小(xms和xmx)之前设置为3G,服务器工作正常.由于我仍然看到很多可用内存并且性能不佳,我将堆大小增加到7G并再次运行负载测试.这次我观察到物理内存被很快吃掉了,系统开始消耗交换空间.后来,tomcat在耗尽交换空间后崩溃了.我-XX:+HeapDumpOnOutOfMemoryError在启动tomcat时包含,但我没有得到任何堆转储.当我查看时/var/log/messages,我看到了kernel: Out of memory: Kill process 2259 (java) score 634 or sacrifice child.
为了提供更多信息,这是我在Linux top命令中看到的堆大小设置为3G和7G时的内容
xms&xmx = 3G(工作正常):
在启动tomcat之前:
Mem: 10129972k total, 1135388k used, 8994584k free, 19832k buffers
Swap: 2097144k total, 0k used, 2097144k free, 56008k cached
Run Code Online (Sandbox Code Playgroud)启动tomcat后:
Mem: 10129972k total, 3468208k used, 6661764k free, 21528k buffers
Swap: 2097144k total, 0k used, 2097144k free, 143428k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2257 tomcat 20 0 5991m …Run Code Online (Sandbox Code Playgroud)我们最近对生产系统的观察告诉我们Java容器的驻留内存使用量增长了.关于这个问题,我们已经做了一些调查,以了解为什么java进程使用像pmap这样的本机工具消耗比Heap + Thread Stacks + Shared Objects + Code Cache +等更多的内存.结果,我们发现了一些由本机进程分配的64M内存块(成对)(可能使用malloc/mmap):
0000000000400000 4K r-x-- /usr/java/jdk1.7.0_17/bin/java
0000000000600000 4K rw--- /usr/java/jdk1.7.0_17/bin/java
0000000001d39000 4108K rw--- [ anon ]
0000000710000000 96000K rw--- [ anon ]
0000000715dc0000 39104K ----- [ anon ]
00000007183f0000 127040K rw--- [ anon ]
0000000720000000 3670016K rw--- [ anon ]
00007fe930000000 62876K rw--- [ anon ]
00007fe933d67000 2660K ----- [ anon ]
00007fe934000000 20232K rw--- [ anon ]
00007fe9353c2000 45304K ----- [ anon ]
00007fe938000000 65512K rw--- [ anon ]
00007fe93bffa000 …Run Code Online (Sandbox Code Playgroud) 我用C编写了一个库,它消耗了大量内存(数百万个小块).我写了一个使用这个库的ac程序.我写了一个使用相同库的java程序.Java程序是库周围非常薄的层.基本上只有一个本地方法被调用,所有的工作都会在几个小时之后完成.使用java调用接口,Java和本机库之间没有进一步的通信.也没有Java对象占用了大量的内存.
所以c程序和Java程序非常相似.整个计算/内存分配发生在本机库中.仍然.执行时,c程序消耗3GB内存.但Java程序消耗4.3GB!(顶部报告的VIRT金额)
我检查了Java进程的内存映射(使用pmap).图书馆只使用40MB.因此,Java加载的其他库不是原因.
有没有人对这种行为有解释?
编辑:感谢您的答案到目前为止.为了让多一点更清晰:Java代码什么也不做,但调用本地库ONCE!java堆是标准大小(可能是60MB)并且未使用(除了包含main方法的一个类和调用本机库的另一个类).
本机库方法是一个长期运行的方法,并且可以执行大量的malloc和frees.碎片化也是我自己想到的一种解释.但由于没有Java代码处于活动状态,因此Java程序和c程序的碎片行为应该相同.由于它不同,我还假设在c程序或Java程序中运行时使用的malloc实现是不同的.
想象你有一个用c#编写的应用程序(单个进程)
默认情况下,应用程序正在分配巨大的虚拟内存,远远超过其需要(例如,驻留内存大约为10mb,而虚拟内存大约为几GB).
在Java中,可以使用一个选项来限制它 java -mx128m
我怎么能为.net/mono应用程序做同样的事情?还有一个问题:是否可以强制/更改GC选项以始终保持尽可能低的内存使用率(尽快收集,而不是在系统内存不足时)
基本上我的目标是创建一个内存占用最小的.net应用程序
编辑:为了使它更清楚我插入这个场景,因为几乎每个.net应用程序似乎都有类似的问题:
我运行monodevelop,它是单声道下的c#应用程序 - 它占用1800 MB的虚拟内存,而它只使用291 MB的驻留内存.这意味着该应用程序仅使用少于300mb的内存,但由于未知原因它要求1800MB.这个原因是我想要发现的,以及如何防止它这样做.
对于大多数用户来说,这可能不是问题,但是当任务受到虚拟内存的限制时,在SGE等集群上运行的应用程序可能会出现问题.
我有一个新的VPS来运行我和一些好友制作的一些java程序.我用这样的一行开始这个过程:
java -Xmx512M -jar program.jar
Run Code Online (Sandbox Code Playgroud)
在我们的旧VPS上,您可以使用'top'命令查看正在使用的虚拟和驻留内存量.它会使用600-700mb的虚拟内存.现在在我们的新VPS上,使用相同的命令,虚拟内存似乎总是比-Xmx值多出约2GB.因此,虚拟内存大约在600-700mb左右,而不是2700-3000mb.
旧的VPS运行CentOS 5.7,新的运行CentOS 6.2.两者都运行JRE 1.7u3 64bit.
为什么这样,我该如何解决?
编辑:顶部
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
27645 pyro 20 0 3003m 270m 10m S 5.0 1.7 1:19.18 java -Xmx512M -jar cserver.jar
Run Code Online (Sandbox Code Playgroud)
另一个编辑:我不怀疑为什么虚拟内存使用的内存比java命令行中指定的多.我在质疑为什么它比以前使用了更多.
我有一个在Linux服务器上运行的独立Java问题.我用-Xmx256m启动了jvm.我附加了一个JMX监视器,可以看到堆永远不会真正通过256Mb.但是,在我的linux系统上运行top命令时,我可以看到:
1)首先,此过程的RES内存使用量约为350Mb.为什么?我想这是因为堆外的内存?
2)其次,这个过程的VIRT内存使用量不断增长和增长.它永远不会停止!它现在显示在2500Mb!我有泄漏吗?但堆不会增加,它只是循环!
最终这会带来问题,因为系统的交换不断增长并最终导致系统死亡.
有什么想法发生了什么?
我想问的一个重要问题是,这可能是我的代码而不是JVM,kernal等的一些情况.例如,如果线程数量不断增长,那么这符合我观察的描述吗?你可以建议我注意哪些类似的东西?
我正在Windows 8.1 64bit上开发java swing应用程序,带有4GB RAM,JDK版本为8u20 64bit.
问题是当我使用带有Monitor选项的Netbeans Profiler启动应用程序时.
加载第一个Jframe时,应用程序内存堆约为18mb,JVM进程大小约为50mb(image1).
然后当我启动包含带有webView的JFxPanel的其他Jframe时,Heap跳转到45mb并且JVM 进程非常快地跳到700mb(image2),这非常令人困惑.然后,当我关闭第二个JFrame并且它被释放并调用System.gc()并且JVM执行GC(在大多数情况下)时,堆降低到大约20mb,但JVM进程从不丢弃(image3).
为什么内存堆(45 Mb)和JVM进程(699 Mb)之间存在巨大差异?为什么JVM需要所有内存?以及如何减少这个数额?我正在使用这些vm选项启动应用程序:
-Xms10m -Xmx60m -Xss192k
-XX:+UseG1GC -XX:MinHeapFreeRatio=5
-XX:MaxHeapFreeRatio=10 -XX:PermSize=20m
-XX:MaxPermSize=32m
Run Code Online (Sandbox Code Playgroud)
编辑: -我刚刚读到该链接JVM内存使用失控的问题,他有同样的问题,但情况不同他的堆大小是JVM进程内存总大小的33%,在我的情况下小于7 %,他同时做多个工作(Tomcat webapp),我没有(java swing应用程序),他没有使用我所做的相同VM参数启动他的应用程序.
更新: - 在第一个JFrame启动后(image1)

第二个JFrame启动后(image2)

第二个JFrame关闭后(image3)

编辑2: - 我刚刚使用上面相同的VM参数尝试了相同的应用程序并添加了
-client
-XX:+UseCompressedOops
Run Code Online (Sandbox Code Playgroud)
并且使用了JDK 8u25 32位,因为如本答案/sf/answers/1083005381/中所述,64位版本不包含JRE中的客户端文件夹,并将忽略-client参数.
结果是当第二个JFrame打开时,总内存进程跳转到540Mb,并且堆大小(在三个点中)与64位版本中的数量几乎相同,这是否确认这是一个与问题相关的问题到JVM(相同的堆大小和总进程大小的260Mb差异)?