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的东西:

 

 

上面最前变的"Attach Listener" 是线程名, 紧跟其后的 daemon是线程的守护状态,

你可能会遇到下面的状况(俺遇到的不是,下面的状况是从别人那转过来的)

 

其中主线程不是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,上面的办法肯定可以解决也是最应该用的办法,但是我相信很对于很多人尤其是入行不太久的看到这里,应该还是乱乱的,尝试还是解决不掉

posted @ 2020-03-02 22:39  King-DA  阅读(760)  评论(0编辑  收藏  举报