JVM崩溃Log日志分析和jvm参数在哪里设置和tomcat优化(全)

更新时间:2023-07-20 07:35:20 阅读: 评论:0

JVM崩溃Log⽇志分析和jvm参数在哪⾥设置和tomcat优化
(全)
⼀:JVM崩溃Log⽇志分析
Java的应⽤有时候会因为各种原因Crash,这时候会产⽣⼀个类似java_errorpid.log的错误⽇志。可以拿到了
这个⽇志,怎样分析Crash的原因呢?下⾯我们来详细讨论如何分析java_errorpid.log的错误⽇志。
⼀. 如何得到这个⽇志⽂件
如果有⼀个严重的错误引起Java进程⾮正常退出,我们叫Crash,这时候会产⽣⼀个⽇志⽂件。缺省情况下,这个
⽂件会产⽣在⼯作⽬录下。但是,可以在Java启动参数通过下⾯的设置,来改变这个⽂件的位置和命名规则。例如:
java -XX:ErrorFile=/var/log/java/java_error_%p.log
就将这个错误⽂件放在/var/log/java下,并且以java_error_pid.log的形式出现。
⼆.产⽣错误的原因
造成严重错误的原因有多种可能性。Java虚拟机⾃⾝的Bug是原因之⼀,但是这种可能不是很⼤。在绝⼤多数情况下,
是由于系统的库⽂件、API或第三⽅的库⽂件造成的;系统资源的短缺也有可能造成这种严重的错误。在发⽣了Crash
之后,如果⽆法定位根本原因,也应该迅速找到Work Around的⽅法。
三.对⽇志⽂件的分析
⾸先要检查⽇志的⽂件头:例如,下⾯是从⼀个客户发过来的错误⽇志的⽂件头
-------------------------------------
#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0815e87e, pid=7268, tid=4360
#
# Java VM: Java HotSpot(TM) Server VM (1.4.2_13-b06 mixed mode)
# Problematic frame:
# V [jvm.dll+0x15e87e]
#
--------------------------------------
⽂件头中有很多有⽤的信息,“EXCEPTION_ACCESS_VIOLATION ”意味着Java应⽤Crash的时候,
正在运⾏JVM⾃⼰的代码,⽽不是外部的Java代码或其他类库代码。这种情况很可能是JVM的Bug,但是
也不⼀定。除了“EXCEPTION_ACCESS_VIOLATION ”,还有可能是别的信息,例如“SIGSEGV(0xb)”,
意味着JVM正在执⾏本地或JNI的代码;“EXCEPTION_STACK_OVERFLOW”意味着这是个栈溢出的错误。
(**********看到这⾥我们知道我报错时正在运⾏JVM⾃⼰的代码,⽽不是外部的Java代码或其他类库代码*********)
另外⼀个有⽤的信息就是:
# Problematic frame:
# V [jvm.dll+0x15e87e]
它说明Crash的时候,JVM正在从哪个库⽂件执⾏代码。除了“V”以外,还有可能是“C”、“j”、“v”、“J”。具体的表⽰意思如下:
FrameType Description:
C: Native C frame
j: Interpreted Java frame
V: VMframe
v: VMgenerated stub frame
J: Other frame types, including compiled Java frames
(**********看到这⾥我们知道我报错时是V: VMframe这种情况*********)
⽂件头之后,是当前线程的DUMP信息,线程之后是JVM进程的DUMP信息,包括所有线程的状态、地址和ID。最后还有JVM状态,
Heap状态,动态连接库等等的信息。这些烦乱的信息中,包含有⾮常有⽤的信息。下⾯我们根据⼏个具体的实例来分析Java虚拟机Crash的典型例⼦。
四.内存回收引起的Crash
内存回收引起的Crash有以下的特点:在⽇志⽂件头⼀般有“ EXCEPTION_ACCESS _VIOLATION”和
“# Problematic frame: # V [jvm.dll+....”的信息,意味着这是在JVM内部处理,⽽且多半是JVM的Bug。
(**********看到这⾥我们知道我报错时意味着这是在JVM内部处理,⽽且多半是JVM的Bug*********)
对于这类问题,最快的⽅法就是绕过它。
另外,在Thread的DUMP信息最后,还能看到有关内存回收的⾏为例如:
--------------- T H R E A D ---------------
Current thread (0x00a56668): VMThread [id=4360]
siginfo: ExceptionCode=0xc0000005, reading address 0x00000057
Registers:
........
Stack: [0x03cf0000,0x03d30000), sp=0x03d2fc18, free space=255k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
大唐情史床戏V [jvm.dll+0x15e87e]
VM_Operation (0x063efbac): full generation collection, mode: safepoint, requested by thread 0x040f83f8
------------------------------------------------------------
可以清楚的看到JVM正在做 “full generation collection”。另外还有可能看到,其他的回收⾏为:
generation collection for allocation
full generation collection
parallel gc failed allocation
parallel gc failed permanent allocation
parallel gc system gc
(***********这些错,俺都没碰到***********)
对于内存回收的错误,⼀般采取改变回收的算法和参数的⽅法来绕过去。例如,来⾃客户的⽇志除了上⾯的
⽇志信息,在⽇志中Heap信息中还能发现⼀些其他信息:
--------------------------------------------------------------
Heap
def new generation total 22592K, ud 19530K [0x10010000, 0x11890000, 0x138f0000)
eden space 20096K, 97% ud [0x10010000, 0x11322bd8, 0x113b0000)
from space 2496K, 0% ud [0x113b0000, 0x113b0000, 0x11620000)
to space 2496K, 0% ud [0x11620000, 0x11620000, 0x11890000)
tenured generation total 190696K, ud 100019K [0x138f0000, 0x1f32a000, 0x30010000)
the space 190696K, 52% ud [0x138f0000, 0x19a9cf38, 0x19a9d000, 0x1f32a000)
compacting perm gen total 38656K, ud 38588K [0x30010000, 0x325d0000, 0x34010000)
the space 38656K, 99% ud [0x30010000, 0x325bf038, 0x325bf200, 0x325d0000)
-
---------------------------------------------------------------
上⾯的信息能看出在Crash的时候,JVM的PermSize空间⼏乎已经消耗完了,并且回收算法在压缩Perm空间的时候出了错。
因此,建议改变内存回收的算法,或扩⼤PermSize和MaxPermSize的数值。
(*******这个倒是可以尝试*******)
五.栈溢出引起的Crash
Java代码引起的栈溢出,通常不会引起JVM的Crash,⽽是抛出⼀个Java异常:java.lang.StackOverflowError。
但是在Java虚拟机中,Java的代码和本地C或C++代码公⽤相同的Stack。这样,在执⾏本地代码所造成的栈溢出,性别决定
就有可能引起JVM的Crash了。
栈溢出引起的Crash会在⽇志的⽂件头中看到“EXCEPTION_STACK_OVERFLOW”字样。另外,在当前线程的Stack
信息中也能发现⼀些信息。例如下⾯的例⼦:
注意到英语
-----------------------------------------------------------------------------------
# An unexpected error has been detected by HotSpot Virtual Machine:
#
# EXCEPTION_STACK_OVERFLOW (0xc00000fd) at pc=0x10001011, pid=296, tid=2940
#
# Java VM: Java HotSpot(TM) Client VM (1.6-internal mixed mode, sharing)
# Problematic frame:
# C [App.dll+0x1011]
#
--------------- T H R E A D ---------------
Current thread (0x000367c0): JavaThread "main" [_thread_in_native, id=2940]
:
Stack: [0x00040000,0x00080000), sp=0x00041000, free space=4k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [App.dll+0x1011]
C [App.dll+0x1020]
C [App.dll+0x1020]
:
C [App.dll+0x1020]
C [App.dll+0x1020]
...<more frames>...
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j Test.foo()V+0
j Test.main([Ljava/lang/String;)V+0
v ~StubRoutines::call_stub
--------------------------------------------------------------------------------
在上⾯的信息中,可以发现这是个栈溢出的错误。并且当前栈剩余的空间已经很⼩了(free space =4k)。
因此建议将JVM的Stack的尺⼨调⼤,主要设计两个参数:“-Xss” 和“-XX:StackShadowPages=n”。
⼆:
在哪⾥设置,分好⼏种情况:
1、集成开发环境下启动并使⽤JVM,如eclip需要修改根⽬录⽂件eclip.ini;
2、Windows服务器下安装版Tomcat,可使⽤⼯具(tomcat⽬录下)和直接修改注册表两种⽅式修改Jvm参数;
3、Windows服务器解压版Tomcat注册Windows服务,⽅法同上;
4、解压版本的Tomcat, 通过startup.bat启动tomcat加载配置的,在tomcat 的bin 下catalina.bat ⽂件内添加;
5、Linux服务器Tomcat设置JVM,修改TOMCAT_HOME/bin/catalina.sh;
三:tomcat优化(全)
1.内存设置(VM参数调优)
(1). Windows环境下,是tomcat解压版(执⾏startup.bat启动tomcat) ,解决办法:
修改“%TOMCAT_HOME%\bin\catalina.bat”⽂件,在⽂件开头增加如下设置:
t JAVA_OPTS=-Xms512m -Xmx512m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=512m
备注:⼀定加在catalina.bat最前⾯。
一线员工
(2). Windows环境下,是tomcat安装版(利⽤windows的系统服务启动tomcat),解决办法:
梦见牙齿断了修改注册表HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Procrun 2.0\Tomcat6\Parameters\JavaOptions
原值为:
-Dcatalina.home=E:\Tomcat 6.0
-Dcatalina.ba=E:\Tomcat 6.0
-dord.dirs=E:\Tomcat 6.0\common\endord
健康生活英语作文-pdir=E:\Tomcat 6.0\temp
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
-Djava.fig.file=E:\Tomcat 6.0\conf\logging.properties
-Djava.fig.file=E:\Tomcat 6.0\conf\logging.properties
加⼊:
Xms512m -Xmx512m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=512m
重起tomcat服务,设置⽣效。
(3). Linux环境下, ,解决办法:
修改“%TOMCAT_HOME%\bin\catalina.sh”⽂件,在⽂件开头增加如下设置:JAVA_OPTS=’-Xms256m -Xmx512m’
各参数详解:
-Xms:设置JVM初始内存⼤⼩(默认是物理内存的1/64)
-Xmx:设置JVM可以使⽤的最⼤内存(默认是物理内存的1/4,建议:物理内存80%)
-Xmn:设置JVM最⼩内存(128-256m就够了,⼀般不设置)
默认空余堆内存⼩于 40%时,JVM就会增⼤堆直到-Xmx的最⼤限制;空余堆内存⼤于70%时,JVM会减少堆直到-Xms的最⼩限制。因此服务器⼀般设置-Xms、 -Xmx相等以避免在每次GC 后调整堆的
⼤⼩。
在较⼤型的应⽤项⽬中,默认的内存是不够的,有可能导致系统⽆法运⾏。常见的问题是报Tomcat内存溢出错误“java.lang.OutOfMemoryError: Java heap space”,从⽽导致客户端显⽰500错误。
-XX:PermSize :为JVM启动时Perm的内存⼤⼩
-XX:MaxPermSize :为最⼤可占⽤的Perm内存⼤⼩(默认为32M)
-XX:MaxNewSize,默认为16M
PermGen space的全称是Permanent Generation space,是指内存的永久保存区域,这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中,它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运⾏期对PermGen space进⾏清理,所以如果你的应⽤中有很CLASS的话,就很可能出现“java.lang.OutOfMemoryError: PermGen space”错误。
对于WEB项⽬,jvm加载类时,永久域中的对象急剧增加,从⽽使jvm不断调整永久域⼤⼩,为了避免调整),你可以使⽤更多的参数配置。如果你的WEB APP 下都⽤了⼤量的第三⽅jar, 其⼤⼩超过了jvm默认的⼤⼩,那么就会产⽣此错误信息了。
其它参数:
杨家瑞-XX:NewSize :默认为2M,此值设⼤可调⼤新对象区,减少Full GC次数
-XX:NewRatio :改变新旧空间的⽐例,意思是新空间的尺⼨是旧空间的1/8(默认为8)
-XX:SurvivorRatio :改变Eden对象空间和残存空间的尺⼨⽐例,意思是Eden对象空
间的尺⼨⽐残存空间⼤survivorRatio+2倍(缺省值是10)
-XX:urParNewGC 可⽤来设置并⾏收集【多CPU】
-XX:ParallelGCThreads 可⽤来增加并⾏度【多CPU】
-XXUParallelGC 设置后可以使⽤并⾏清除收集器【多CPU】
2.修改tomcat让其⽀持NIO
修改前:
protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443"/>
修改成⽀持NIO的类型,配置如下:
protocol="http11.Http11NioProtocol " connectionTimeout="20000" redirectPort="8443" />
3.并发数设置
默认的tomcat配置,并发测试时,可能30个USER上去就当机了。
添加
maxThreads="600" //最⼤线程数
minSpareThreads="100" //初始化时创建的线程数
maxSpareThreads="500" //⼀旦线程超过这个值,Tomcat会关闭不需要的socket线程
acceptCount="700"//指定当所有可以使⽤的处理请求的线程数都被使⽤时,可以放到
处理队列中的请求数,超过这个数的请求将不予处理
connectionTimeout="20000"
redirectPort="8443" />
或者
name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="500" minSpareThreads="400" />
executor="tomcatThreadPool" port="80" protocol="HTTP/1.1" connectionTimeout="20000" enableLookups="fal"
redirectPort="8443" URIEncoding="UTF-8" acceptCount="1000" />
4.Java虚拟机调优
应该选择SUN的JVM,在满⾜项⽬需要的前提下,尽量选⽤版本较⾼的JVM,⼀般来说⾼版本产品在速度和效率上⽐低版本会有改进。 JDK1.4⽐JDK1.3性能提⾼了近10%-20%,JDK1.5⽐JDK1.4性能提⾼25%-75%。延迟退休新政策
5.禁⽤DNS查询
设置enableLookups="fal":
enableLookups="fal" redirectPort="8443" URIEncoding="UTF-8" acceptCount="1000" />
enableLookups="fal" redirectPort="8443" URIEncoding="UTF-8" acceptCount="1000" />
 当web应⽤程序向要记录客户端的信息时,它也会记录客户端的IP地址或者通过域名服务器查找机器名转换为IP地址。DNS查询需要占⽤⽹络,并且包括可能从很多很远的服务器或者不起作⽤的服务器上去获取对应的IP的过程,这样会消耗⼀定的时间。为了消除DNS查询对性能的影响我们可以关闭 DNS查询,⽅式是修改l⽂件中的enableLookups参数值为fal。
6.设置解决乱码问题
URIEncoding="UTF-8" acceptCount="1000" />

本文发布于:2023-07-20 07:35:20,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1088804.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:内存   设置   信息   服务器   空间   回收
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图