我遇到了JVM无法用Java分配内存的问题
OpenJDK 64位服务器VM警告:INFO: os :: commit_memory(0x0000000734880000,880279552,0)失败; error ='无法分配内存'(errno = 12)
没有足够的内存供Java Runtime Environment使用 继续。本机内存分配(mmap)无法映射880279552 用于提交保留内存的字节。错误报告文件,其中包含更多内容 信息另存为: /home/ec2-user/tools/apache/apache-tomcat-9.0.6/bin/hs_err_pid23366.log java.lang.NullPointerException
这是我的内存统计数据
MemTotal: 8166744 kB
MemFree: 3788780 kB
MemAvailable: 3861816 kB
Buffers: 0 kB
Cached: 286536 kB
SwapCached: 0 kB
Active: 4030520 kB
Inactive: 182596 kB
Active(anon): 3926808 kB
Inactive(anon): 24892 kB
Active(file): 103712 kB
Inactive(file): 157704 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 192 kB
Writeback: 0 kB
AnonPages: 3926652 kB
Mapped: 72652 kB
Shmem: 25120 kB
Slab: 100300 kB
SReclaimable: 60032 kB
SUnreclaim: 40268 kB
KernelStack: 5616 kB
PageTables: 21632 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 4083372 kB
Committed_AS: 5723980 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 0 kB
VmallocChunk: 0 kB
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
ShmemPmdMapped: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 286720 kB
DirectMap2M: 8101888 kB
这似乎是重复的JVM堆内存不足问题。与此问题最接近的是this thread
但是,不同之处在于,在链接线程中,用户的可用空间较少,并且JVM试图分配更大的内存(打开和关闭的情况)。
在我的情况下,JVM试图分配880279552 btes(0.8 GB),而我的可用内存(以上)为3.7 GB。 JVM尽管有近4倍的可用内存却无法分配它,这可能是什么原因?附带的问题:为什么要分配0.8 GB的内存。这正常吗?有没有一种方法可以通过工具更深入地找出这种分配?谁能指向一个资源来更好地了解上述内存状态?
这是setenv.sh(这是8 GB RAM计算机)中的JVM配置
export CATALINA_HOME="/home/ec2-user/tools/apache/apache-tomcat-9.0.6/"
export JAVA_OPTS="-Xms2048m -Xmx4096m -DJDBC_CONNECTION_STRING=jdbc:mysql://localhost:3306/databasename?autoReconnect=true -DJDBC_DATABASER=dbname-DJDBC_USER=username-DJDBC_PASSWORD=password-DAPPLICATION_PRO$
export JAVA_HOME="/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.201.b09-0.amzn2.x86_64"
崩溃后,这是消耗内存最多的服务,而在Java消耗了3.1 GB之后,MySQL使用了0.5 GB(再次确认第一个内存统计信息屏幕快照,其中说有4 GB内存可用/可用)
PID PPID CMD %MEM %CPU
4890 1 /usr/lib/jvm/java-1.8.0-ope 38.1 1.0
23204 1 /usr/sbin/mysqld --daemoniz 7.1 0.9
26056 3484 node /home/ec2-user/tools/j 1.3 111
3548 3484 node /home/ec2-user/tools/j 1.1 0.3
3484 1 PM2 v3.5.0: God Daemon (/ro 0.7 0.6
26067 26056 /root/.nvm/versions/node/v1 0.3 7.5
26074 26067 /root/.nvm/versions/node/v1 0.3 7.5
3610 3548 /root/.nvm/versions/node/v1 0.3 0.0
3624 3610 /root/.nvm/versions/node/v1 0.3 0.0
感谢您帮助我们理解这一点。
答案 0 :(得分:1)
@vlumi和其他人试图以“没有可用的直接内存”的正确方向指导我。但是,我还开始遇到“堆内存不足”和“内存不足”的其他问题。
问题如下:在tomcat服务器上重新部署WAR后,现有线程没有被杀死,并且它们的引用仍然保留,因此GC无法清理它。原始的元空间(以前称为PermGen)有80MB,随着应用程序的更改,该空间增加到125MB。重新部署后,返回到80MB,VisualVM Profiler上的元空间显示为170MB,在下一次重新部署中显示为210。这清楚地表明,在再进行十二次重新部署(这是一个测试服务器)之后,JVM会用完RAM空间以用于分配并抛出堆内存。
为解决此问题,我们在Jenkins作业中添加了tomcat7:shutdown(或通过shell脚本重新启动)。停止和启动tomcat能够像以前一样默认返回到元空间。其他一些人则试图杀死jawa进程,以便杀死所有线程。
感谢大家的贡献。这是该网站的link,对您最了解实际情况的帮助最大。