linux系统下报错为:直接在tomcat的bin目录下生成一个错误文件。
# # There is insufficient memory for the Java Runtime Environment to continue. # Native memory allocation (mmap) failed to map 567279616 bytes for committing reserved memory. # Possible reasons: # The system is out of physical RAM or swap space # In 32 bit mode, the process size limit was hit # Possible solutions: # Reduce memory load on the system # Increase physical memory or swap space # Check if swap backing store is full # Use 64 bit Java on a 64 bit OS # Decrease Java heap size (-Xmx/-Xms) # Decrease number of Java threads # Decrease Java thread stack sizes (-Xss) # Set larger code cache with -XX:ReservedCodeCacheSize= # This output file may be truncated or incomplete. # # Out of Memory Error (os_linux.cpp:2627), pid=25371, tid=140459653363456 # # JRE version: Java(TM) SE Runtime Environment (8.0_73-b02) (build 1.8.0_73-b02) # Java VM: Java HotSpot(TM) 64-Bit Server VM (25.73-b02 mixed mode linux-amd64 compressed oops) # Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again #
这是因为内存溢出所以才报错的。
当时产生错误的原因:启动,关闭tomcat次数过多,使用的关闭命令shutdown.sh未能关闭jvm进程。
实验一:
修改server.xml配置文件。
因为从运维那边得到的信息,只是修改端口号。在使用shutdown.sh关闭的时候,只是修改了配置文件。所以修改了配置文件。但是自己实验过,没用
实验二:
以为webapps下面有挺多的文件。查看以后,这里也是唯一的不同,所以将文件删除后,再次进行实验,还是不行。没用。
实验三:修改两个文件:这次是成功的。
基本原理为启动tomcat时记录启动tomcat的进程id(pid),关闭时强制杀死该进程
1.找到tomcat下bin/catalina.sh文件,vi进去添加点东西,主要是记录tomcat的pid,如下:
大概在第125行左右,添加如下代码
#设置CATALINA_PID(后加)
if [ -z "$CATALINA_PID" ]; then
CATALINA_PID=$PRGDIR/CATALINA_PID
cat $CATALINA_PID
fi
保存即可。
2.vi进shutdown.sh文件,在最后一行如下红圈-force:
3.需要在bin目录下创建文件CATALINA_PID文件
保存即可.
实验四:
从tomcat下项目入手,一般造成这种原因是因为项目中有非守护线程的存在。那么怎么找到改线程呢,请看下面:
利用jdk 提供的jstack可以帮助我们找到:
$JAVA_HOME/bin/jstack <pid>
pid是指进程ID, 用ps -ef|grep tomcat 就可以查看到:
12126即为pid,继续输入jstack 12126会看到如下一堆balabala的东西:
你可能会遇到下面的状况(俺遇到的不是,下面的状况是从别人那转过来的)
其中主线程不是daemon的,所以是这样:
"main" prio=10 tid=0xb6d05000 nid=0x5ea runnable [0xb6ee9000]
java.lang.Thread.State: RUNNABLE
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
- locked <0x871644a8> (a java.net.SocksSocketImpl)
at java.net.ServerSocket.implAccept(ServerSocket.java:462)
at java.net.ServerSocket.accept(ServerSocket.java:430)
at org.apache.catalina.core.StandardServer.await(StandardServer.java:431)
at org.apache.catalina.startup.Catalina.await(Catalina.java:676)
at org.apache.catalina.startup.Catalina.start(Catalina.java:628)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
在"main" 后没有daemon,看到这样的线程状态,顺藤摸瓜,找到对应new Thread的地方setDaemon(true)就可以,痛痛快快的shutdown了:)
你也可能会看到类似下面的状况(我遇到的就是这种情况):
如果你看到类似于"DestroyJavaVM" prio=10 balabala的东西,那么恭喜你,你的程序可能出现了死锁,关于死锁方面的资料可以看着这篇文章点击打开链接看下,这里就不多做介绍了。继续往下看如果发现有waiting on condition等字样说明你的程序如果发现有大量的线程都在处在 Wait on condition,从线程 stack看, 正等待网络读写,这可能是一个网络瓶颈的征兆。因为网络阻塞导致线程无法执行。一种情况是网络非常忙,几乎消耗了所有的带宽,仍然有大量数据等待网络读写;另一种情况也可能是网络空闲,但由于路由等问题,导致包无法正常的到达。所以要结合系统的一些性能观察工具来综合分析,比如 netstat统计单位时间的发送包的数目,如果很明显超过了所在网络带宽的限制 ; 观察 cpu的利用率,如果系统态的 CPU时间,相对于用户态的 CPU时间比例较高;如果程序运行在 Solaris 10平台上,可以用 dtrace工具看系统调用的情况,如果观察到 read/write的系统调用的次数或者运行时间遥遥领先;这些都指向由于网络带宽所限导致的网络瓶颈。另外一种出现 Wait on condition的常见情况是该线程在 sleep,等待 sleep的时间到了时候,将被唤醒。 前面蓝色字体是度娘百出来的结果。详细请点击打开链接。好既然已找到问题所在了,那么接下来就叫给你自己解决了。
ok,上面的办法肯定可以解决也是最应该用的办法,但是我相信很对于很多人尤其是入行不太久的看到这里,应该还是乱乱的,尝试还是解决不掉
本文来自博客园,作者:King-DA,转载请注明原文链接:https://www.cnblogs.com/qingmuchuanqi48/p/12398624.html