相关疑难解决方法(0)

Linux下的Java虚拟内存使用情况,使用的内存过多

我在Linux下运行的Java应用程序有问题.

当我使用默认的最大堆大小(64 MB)启动应用程序时,我看到使用tops应用程序为应用程序分配了240 MB的虚拟内存.这会在计算机上创建一些其他软件的问题,这些软件相对资源有限.

据我所知,无论如何都不会使用保留的虚拟内存,因为一旦达到堆限制OutOfMemoryError就会被抛出.我在Windows下运行相同的应用程序,我发现虚拟内存大小和堆大小相似.

无论如何我可以在Linux下配置用于Java进程的虚拟内存吗?

编辑1:问题不在于堆.问题是,如果我设置一个128 MB的堆,那么Linux仍然会分配210 MB的虚拟内存,这是不需要的.**

编辑2:使用ulimit -v允许限制虚拟内存量.如果大小设置低于204 MB,则应用程序将不会运行,即使它不需要204 MB,只需64 MB.所以我想了解为什么Java需要这么多虚拟内存.这可以改变吗?

编辑3:系统中运行了几个其他应用程序,它们是嵌入式的.系统确实有虚拟内存限制(来自评论,重要细节).

java linux memory virtual-memory

246
推荐指数
5
解决办法
23万
查看次数

跟踪Java中的内存泄漏/垃圾回收问题

这是我一直试图追踪几个月的问题.我有一个运行java应用程序来处理xml提要并将结果存储在数据库中.存在非常难以追踪的间歇性资源问题.

背景: 在生产盒(问题最明显的地方),我没有特别好的访问框,并且无法运行Jprofiler.那个盒子是64位四核,8GB机器运行centos 5.2,tomcat6和java 1.6.0.11.它从这些java-opts开始

JAVA_OPTS="-server -Xmx5g -Xms4g -Xss256k -XX:MaxPermSize=256m -XX:+PrintGCDetails -
XX:+PrintGCTimeStamps -XX:+UseConcMarkSweepGC -XX:+PrintTenuringDistribution -XX:+UseParNewGC"
Run Code Online (Sandbox Code Playgroud)

技术堆栈如下:

  • Centos 64位5.2
  • Java 6u11
  • 雄猫6
  • Spring/WebMVC 2.5
  • Hibernate 3
  • 石英1.6.1
  • DBCP 1.2.1
  • Mysql 5.0.45
  • Ehcache 1.5.0
  • (当然还有许多其他依赖项,尤其是jakarta-commons库)

我能解决的最接近问题的是32位机器,内存要求较低.我确实有控制权.我已经使用JProfiler探测它并修复了许多性能问题(同步问题,预编译/缓存xpath查询,减少了线程池,删除了不必要的hibernate预取,以及在处理过程中过度热心的"缓存变暖").

在每种情况下,分析器都会将这些资源显示为由于某种原因而占用大量资源,并且一旦发生变化,这些资源就不再是主要资源.

问题: JVM似乎完全忽略了内存使用设置,填满了所有内存并且没有响应.对于面向客户的人来说,这是一个问题,他们期望定期投票(5分钟和1分钟重试),以及我们的运营团队,他们经常被告知箱子已经无响应并且必须重新启动它.这个盒子上没有其他重要的东西.

问题似乎是垃圾收集.我们正在使用ConcurrentMarkSweep(如上所述)收集器,因为原始STW收集器导致JDBC超时并变得越来越慢.日志显示,随着内存使用量的增加,这开始引发cms失败,并回到最初的世界收藏家,然后似乎没有正确收集.

然而,运行jprofiler,"运行GC"按钮似乎很好地清理内存而不是显示增加的占用空间,但由于我无法将jprofiler直接连接到生产盒,并且解决已证实的热点似乎无法正常工作我是留下了调整垃圾收集盲人的伏都教.

我尝试过的:

  • 分析和修复热点.
  • 使用STW,并行和CMS垃圾收集器.
  • 使用最小/最大堆大小以1/2,2/4,4/5,6/6为增量运行.
  • 使用permgen空间以256M为增量运行,最高可达1Gb.
  • 以上的许多组合.
  • 我也咨询过JVM [调优参考](http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html),但是找不到任何解释这种行为的东西或者_which_ tuning的任何例子在这种情况下使用的参数.
  • 我也在(离线模式)尝试了jprofiler,与jconsole,visualvm连接,但是我似乎找不到任何可以插入我的gc日志数据的东西.

不幸的是,问题也偶尔会出现,它似乎是不可预测的,它可以运行几天甚至一周而没有任何问题,或者它可以在一天内失败40次,而且我唯一可以看到的是一致的是垃圾收集正在起作用.

任何人都可以提出以下建议:
a)为什么JVM在配置为最大值小于6时使用8个物理演出和2 gb交换空间
.b)对GC调整的引用实际上解释或给出了合理的示例什么样的设置使用高级集合.
c)对最常见的java内存泄漏的引用(我理解无人认领的引用,但我的意思是在库/框架级别,或者在数据结构中更像inherenet,比如hashmaps).

感谢您提供的任何和所有见解.

编辑
Emil H:
1)是的,我的开发集群是生产数据的镜像,直到媒体服务器.主要的区别是32/64bit和可用的RAM量,我无法轻易复制,但代码和查询和设置是相同的.

2)有一些遗留代码依赖于JaxB,但在重新排序作业以试图避免调度冲突时,我通常会删除执行,因为它每天运行一次.主解析器使用调用java.xml.xpath包的XPath查询.这是一些热点的来源,其中一个查询没有被预编译,两个对它们的引用都是硬编码的字符串.我创建了一个线程安全缓存(hashmap),并将对xpath查询的引用考虑为最终的静态字符串,从而显着降低了资源消耗.查询仍然是处理的很大一部分,但应该是因为这是应用程序的主要责任.

3)另外一个注释,另一个主要消费者是来自JAI的图像操作(从饲料中重新处理图像).我不熟悉java的图形库,但从我发现它们并没有特别漏洞.

(感谢目前为止的答案,伙计们!)

更新:
我能够使用VisualVM连接到生产实例,但它已禁用GC可视化/运行GC选项(尽管我可以在本地查看).有趣的是:VM的堆分配服从JAVA_OPTS,并且实际分配的堆正好坐在1-1.5 gigs,并且似乎没有泄漏,但是盒级监控仍显示泄漏模式,但它是没有反映在VM监控中.这个盒子上没有别的东西在跑,所以我很难过.

java profiling garbage-collection memory-leaks

79
推荐指数
1
解决办法
3万
查看次数

驻留集大小(RSS)与在Docker容器中运行的JVM的Java总提交内存(NMT)之间的差异

场景:

我有一个在docker容器中运行的JVM.我使用两个工具进行了一些内存分析:1)top 2)Java Native Memory Tracking.这些数字看起来很混乱,我试图找出导致差异的原因.

题:

对于Java进程,RSS报告为1272MB,报告的总Java内存为790.55 MB.我怎么能解释内存的其余部分1272 - 790.55 = 481.44 MB去哪了?

为什么我想在SO上查看这个问题后仍然保持这个问题的开放性:

我确实看到了答案,解释也很有道理.但是,从Java NMT和pmap -x获取输出后,我仍然无法具体映射实际驻留和物理映射的Java内存地址.我需要一些具体的解释(详细步骤)来找出导致RSS和Java Total提交内存之间差异的原因.

最高输出

在此输入图像描述

Java NMT

在此输入图像描述

Docker内存统计信息

在此输入图像描述

图表

我有一个运行48小时以上的码头集装箱.现在,当我看到一个图表包含:

  1. 给予docker容器的总内存= 2 GB
  2. Java Max Heap = 1 GB
  3. 承诺总量(JVM)=始终小于800 MB
  4. 堆使用(JVM)=始终小于200 MB
  5. 非堆使用(JVM)=始终小于100 MB.
  6. RSS =大约1.1 GB.

那么,在1.1 GB(RSS)和800 MB(Java Total committed memory)之间占用的内存是什么?

在此输入图像描述

java linux memory jvm docker

34
推荐指数
1
解决办法
1万
查看次数

为什么即使堆等大小稳定,Sun JVM也会继续消耗更多的RSS内存?

在过去的一年里,我在应用程序的Java堆使用方面做了很大的改进 - 减少了66%.为此,我一直在通过SNMP监控各种指标,例如Java堆大小,cpu,Java非堆等.

最近,我一直在监视JVM有多少实内存(RSS,驻留集)并且有点惊讶.JVM消耗的实际内存似乎完全独立于我的应用程序堆大小,非堆,eden空间,线程数等.

堆栈大小由Java SNMP Java堆使用图表测量http://lanai.dietpizza.ch/images/jvm-heap-used.png

以KB为单位的实内存.(例如:1 MB KB = 1 GB) Java堆使用图http://lanai.dietpizza.ch/images/jvm-rss.png

(堆图中的三个凹陷对应于应用程序更新/重新启动.)

这对我来说是一个问题,因为JVM正在消耗的所有额外内存都是"窃取"内存,可供操作系统用于文件缓存.实际上,一旦RSS值达到~2.5-3GB,我开始看到响应时间变慢,应用程序的CPU利用率更高,主要是IO等待.正如某些点对交换分区的分页启动.这都是非常不受欢迎的.

所以,我的问题:

  • 为什么会这样?什么是"引擎盖下"
  • 我该怎么做才能控制JVM的实际内存消耗?

血腥的细节:

  • RHEL4 64位(Linux - 2.6.9-78.0.5.ELsmp#1 SMP Wed Sep 24 ... 2008 x86_64 ... GNU/Linux)
  • Java 6(build 1.6.0_07-b06)
  • 雄猫6
  • 应用程序(按需HTTP视频流)
    • 通过java.nio FileChannels实现高I/O.
    • 数百到数千个线程
    • 数据库使用率低
    • 春天,Hibernate

相关的JVM参数:

-Xms128m  
-Xmx640m  
-XX:+UseConcMarkSweepGC  
-XX:+AlwaysActAsServerClassMachine  
-XX:+CMSIncrementalMode    

-XX:+PrintGCDetails 
-XX:+PrintGCTimeStamps  
-XX:+PrintGCApplicationStoppedTime  
-XX:+CMSLoopWarn  
-XX:+HeapDumpOnOutOfMemoryError 
Run Code Online (Sandbox Code Playgroud)

我如何衡量RSS:

ps x -o command,rss | grep java | grep latest | cut -b 17-
Run Code Online (Sandbox Code Playgroud)

这将进入一个文本文件,并定期读入我的监控系统的RRD数据库.请注意,ps输出Kilo Bytes.


存在的问题及解决方案小号:

虽然最终是ATorras的答案证明最终是正确的,但是kdgregory …

java memory performance jvm sun

33
推荐指数
2
解决办法
1万
查看次数

Java进程的内存无限增长,但MemoryMXBean报告稳定的堆和非堆大小

我正在与一个开发在1GB Linux目标系统上运行的Java GUI应用程序的团队合作.

我们遇到的问题是,我们的java进程使用的内存无限增长,直到Linux最终杀死java进程.

我们的堆内存健康稳定.(我们已广泛地分析了我们的堆)我们还使用MemoryMXBean来监视应用程序的非堆内存使用情况,因为我们认为问题可能就在那里.但是,我们看到报告的堆大小+报告的非堆大小保持稳定.

下面是一个示例,说明在我们的目标系统上运行具有1GB RAM的应用程序时的数字(MemoryMXBean报告的堆和非堆,使用Linux的top命令(常驻内存)监视的Java进程使用的总内存):

在启动时:

  • 提交200 MB堆
  • 40 MB非堆已提交
  • java进程使用的320 MB

1天后:

  • 提交200 MB堆
  • 40 MB非堆已提交
  • java进程使用的360 MB

2天后:

  • 提交200 MB堆
  • 40 MB非堆已提交
  • java进程使用的400 MB

上面的数字只是我们系统表现的"清晰"表示,但它们相当准确且接近现实.如您所见,趋势很明显.运行应用程序几周后,由于系统内存不足,Linux系统开始出现问题.事情开始放缓.再过几个小时,Java进程就被杀了.

经过几个月的分析并试图理解这一点,我们仍然处于亏损状态.我觉得很难找到有关此问题的信息,因为大多数讨论最终都会解释堆或其他非堆内存池.(像Metaspace等)

我的问题如下:

  1. 如果你把它分解,java进程使用的内存包括什么?(除了堆和非堆内存池之外)

  2. 哪些其他潜在来源存在内存泄漏?(本机代码?JVM开销?)一般来说哪些是最可能的罪魁祸首?

  3. 如何监控/分析这个内存?堆+非堆外的所有东西目前对我们来说都是一个黑盒子.

任何帮助将不胜感激.

java linux memory memory-leaks

14
推荐指数
1
解决办法
1142
查看次数

如何查找Java + JNI + C++进程中的内存泄漏

我有一个用 java 编写的项目,使用 JNI 使用 C++ 库。所有的代码都是我们写的,所以我有所有的源代码。

几个小时后,机器内存不足,尽管我的进程只是迭代文件,并且与前一个文件相关的所有内存都被删除。

我确信存在内存泄漏,通常我使用Valgrind,但似乎他不能很好地应对Java,并且认为JVM正在泄漏,即使对于“hello world”java项目也是如此。

我已经通过单元测试测试了 C++ 部分(主要流程),并在单元测试中使用了 valgrind,但没有发现任何泄漏。这并不能证明任何事情,因为我可能会错过很多潜在的流程。

我的主要问题是,如何找到泄漏?

了解谁在消耗内存,是 Java 还是本机部分,这将非常有帮助?他们处于同一过程中。

谢谢。

c++ java memory java-native-interface memory-leaks

6
推荐指数
1
解决办法
1万
查看次数

使用-Xmx1024m的Java进程如何占用3GB驻留内存?

它是Websphere6.1,Solaris 10,JDK 1.5.0_13上的Java Web应用程序.我们将最大堆大小设置为1024m.jmap显示堆状态是健康的.堆内存使用率仅为57%.根本没有OutOfMemory.

但是我们从ps看到了这个java进程的非常高的RSS(3GB).pmap显示了一块1.9G的私有内存.

3785:   /dmwdkpmmkg/was/610/java/bin/java -server -Dwas.status.socket=65370 -X
 Address  Kbytes     RSS    Anon  Locked Pgsz Mode   Mapped File
...
0020A000    2008    2008    2008       -   8K rwx--    [ heap ]
00400000 1957888 1957888 1957888       -   4M rwx--    [ heap ]
8D076000      40      40      40       -   8K rw--R    [ stack tid=10786 ]
...

它是本机代码中的C堆内存泄漏吗?建议找出根本原因的方法是什么?

java memory-leaks

5
推荐指数
1
解决办法
8214
查看次数

Java内存之谜(我有泄漏)?

我有一个在Linux服务器上运行的独立Java问题.我用-Xmx256m启动了jvm.我附加了一个JMX监视器,可以看到堆永远不会真正通过256Mb.但是,在我的linux系统上运行top命令时,我可以看到:

1)首先,此过程的RES内存使用量约为350Mb.为什么?我想这是因为堆外的内存?

2)其次,这个过程的VIRT内存使用量不断增长和增长.它永远不会停止!它现在显示在2500Mb!我有泄漏吗?但堆不会增加,它只是循环!

最终这会带来问题,因为系统的交换不断增长并最终导致系统死亡.

有什么想法发生了什么?


我想问的一个重要问题是,这可能是我的代码而不是JVM,kernal等的一些情况.例如,如果线程数量不断增长,那么这符合我观察的描述吗?你可以建议我注意哪些类似的东西?

java linux memory heap optimization

5
推荐指数
1
解决办法
9421
查看次数

如何在Jboss AS 5.1中追踪非堆JVM内存泄漏?

在升级到运行JRE 1.6_17,CentOS 5 Linux的JBoss AS 5.1之后,JRE进程在大约8小时后耗尽内存(在32位系统上达到3G最大值).这种情况发生在中等负载下群集中的两台服务器上.Java堆使用率稳定下来,但整体JVM占用空间不断增长.线程数非常稳定,最大线程为370个线程,线程堆栈大小设置为128K.

JVM的占地面积达到3G,然后它死于:

java.lang.OutOfMemoryError: requested 32756 bytes for ChunkPool::allocate. Out of swap space?

  Internal Error (allocation.cpp:117), pid=8443, tid=1667668880
  Error: ChunkPool::allocate

当前的JVM内存args是:

-Xms1024m -Xmx1024m -XX:MaxPermSize = 256m -XX:ThreadStackSize = 128

鉴于这些设置,我预计流程足迹将在1.5G左右.相反,它只会持续增长,直到达到3G.

似乎没有一个标准的Java内存工具可以告诉我JVM本机端正在吃掉所有这些内存.(Eclipse MAT,jmap等).关于PID的Pmap只给了我一堆[anon]分配,这些分配并没有多大帮助.如果我没有加载JNI或java.nio类,就会出现此内存问题,据我所知.

如何解决JVM的本机/内部问题以找出所有非堆内存的位置?

谢谢!我正在快速耗尽想法,每8小时重新启动应用服务器不会是一个非常好的解决方案.

java jboss memory-leaks

5
推荐指数
1
解决办法
5980
查看次数

为什么 Java 进程的 RES 内存持续缓慢增长,甚至对于开箱即用的 Spring Boot 管理也是如此?

我在一台 32GB 的机器上运行着 23 个 Java 进程。没有进程指定 JVM 内存参数,例如 Xmx。java -XX:+PrintFlagsFinal -version | grep MaxHeapSize报告最大默认堆大小如预期为 8GB。

每个进程都运行嵌入式 Tomcat(Spring Boot 应用程序(大多数版本为 2.3.4)),除了一个是运行三个 WAR 的独立 tomcat 9 实例。这些应用程序的使用率较低(通常是一名用户每天使用 10 分钟)。它们不是内存或 CPU 密集型的。其中之一是 Spring Boot admin,另一个是 Spring Cloud 的 Eureka 服务注册表。对于这两个,我只有一个主要方法来简单地引导 Spring Boot 应用程序。

然而,RES如顶部所示,每个进程的内存都在逐渐增加。例如,Spring Boot 服务注册表在过去 12 小时内从 1.1GB 增加到 1.5GB。所有进程都显示出类似的小幅增长,RES​​但在同一 12 小时内,总的增长使可用内存减少了 2 GB。过去 12 小时(依此类推)也是如此,直到当前可用内存仅为 4.7GB。

我担心的是,我会继续看到这种趋势(即使没有使用应用程序)。内存永远不会从应用程序中释放,因此可用内存总量持续减少。这是正常的吗,因为也许每个 JVM 都会看到操作系统中的内存仍然可用并且有 8GB 堆空间可供使用?一旦达到操作系统可用内存阈值,JVM 是否会在某个时刻停止占用内存?或者它会一直持续到所有可用内存都被用完为止?

更新

大多数应用程序使用的堆小于 200MB,但堆大小为 1.5 - 2.8GB。堆最大为 8GB。

java linux memory jvm spring-boot

5
推荐指数
1
解决办法
1533
查看次数

解释jemaloc数据可能在堆外泄漏

我在2周前开始搜索不断增长的java内存.我使用以下命令来防止堆增长过多,并进行一些调试.

我正在使用oracle java 8在Ubuntu 16.04上运行,因为openjdk 8没有调试符号我需要让jemaloc提供正确的数据

-XX:NativeMemoryTracking=detail -XX:+UseG1GC -XX:+UseStringDeduplication -Xms64m -Xmx256m -XX:MaxMetaspaceSize=128m -Xss256k
Run Code Online (Sandbox Code Playgroud)

如你所见,我的Xmx设置为256米.但是top目前我的流程显示为1.1G

在使用JProfiler和JVisualVm I以及我在google上可以找到的许多其他东西后,我得出的结论是,这必然是一个堆外问题.

经过多次搜索,我遇到了jemaloc,我读到的关于它的文章似乎很有希望.但是现在解释这些数据我遇到了一些问题.并找出如何指出我的问题的根源.

最高内存使用率

jemaloc图

本机内存跟踪数据

Native Memory Tracking:

Total: reserved=1678MB, committed=498MB
-                 Java Heap (reserved=256MB, committed=256MB)
                            (mmap: reserved=256MB, committed=256MB)

-                     Class (reserved=1103MB, committed=89MB)
                            (classes #14604)
                            (malloc=3MB #32346)
                            (mmap: reserved=1100MB, committed=85MB)

-                    Thread (reserved=26MB, committed=26MB)
                            (thread #53)
                            (stack: reserved=26MB, committed=26MB)

-                      Code (reserved=261MB, committed=96MB)
                            (malloc=17MB #17740)
                            (mmap: reserved=244MB, committed=79MB)

-                        GC (reserved=1MB, committed=1MB)
                            (mmap: reserved=1MB, committed=1MB)

-                  Internal (reserved=6MB, committed=6MB)
                            (malloc=6MB #48332) …
Run Code Online (Sandbox Code Playgroud)

java jvm

2
推荐指数
1
解决办法
581
查看次数