Linux中Tomcat内存溢出

  • 场景:刚开始测试服务器与线上后台都不能上传10分钟以上的视频,后来只要是视频就不能上传,进入服务器查日志得到如下错误:
Caused by: java.lang.OutOfMemoryError: Java heap space
at org.apache.commons.io.output.ByteArrayOutputStream.needNewBuffer(ByteArrayOutputStream.java:122)
at org.apache.commons.io.output.ByteArrayOutputStream.write(ByteArrayOutputStream.java:153)
at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1489)
at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1465)
at org.apache.commons.io.IOUtils.copy(IOUtils.java:1440)
at org.apache.commons.io.IOUtils.toByteArray(IOUtils.java:444)
at com.aone.foottalk.action.backstage.image.ImgTAction.ajaxFileUploads(ImgTAction.java:210)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at ognl.OgnlRuntime.invokeMethod(OgnlRuntime.java:892)
at ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1294)
at ognl.ObjectMethodAccessor.callMethod(ObjectMethodAccessor.java:68)
at com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor.callMethodWithDebugInfo(XWorkMethodAccessor.java:117)
at com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor.callMethod(XWorkMethodAccessor.java:108)
at ognl.OgnlRuntime.callMethod(OgnlRuntime.java:1370)
at ognl.ASTMethod.getValueBody(ASTMethod.java:91)
at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
at ognl.SimpleNode.getValue(SimpleNode.java:258)
at ognl.Ognl.getValue(Ognl.java:467)
at ognl.Ognl.getValue(Ognl.java:431)
at com.opensymphony.xwork2.ognl.OgnlUtil$3.execute(OgnlUtil.java:352)
at com.opensymphony.xwork2.ognl.OgnlUtil.compileAndExecuteMethod(OgnlUtil.java:404)
at com.opensymphony.xwork2.ognl.OgnlUtil.callMethod(OgnlUtil.java:350)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:430)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:290)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:251)
at org.apache.struts2.interceptor.DeprecationInterceptor.intercept(DeprecationInterceptor.java:41)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)
at org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:256)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245)

/-- Encapsulated exception ------------
  • 百度得知内存溢出,继续百度查找如下解决办法:(原文百度头几条都有)
  • linux中tomcat内存溢出解决办法 :查看日志常见的一般会有下面三种情况:
  1. OutOfMemoryError: Java heap space
  2. OutOfMemoryError: PermGen space
  3. OutOfMemoryError: unable to create new native thread.
  • 1与2情况通常发生在一起进行操作,通过在linux中的catalina.sh文件最前面加入如下语句,这个文件在tomcat -->bin目录下。
JAVA_OPTS='-Xms1024m -Xmx1024m -XX:PermSize=256M -XX:MaxNewSize=512m -XX:MaxPermSize=512m'
  • 3是无法创建新的线程。
这种现象比较少见,也比较奇怪,主要是和jvm与系统内存的比例有关。这种怪事是因为JVM已经被系统分配了大量的内存(比如1.5G),并且它至少要占用可用内存的一半。有人发现,在线程个数很多的情况下,你分配给JVM的内存越多,那么,上述错误发生的可能性就越大。每一个32位的进程最多可以使用2G的可用内存,因为另外2G被操作系统保留。这里假设使用1.5G给JVM,那么还余下500M可用内存。这 500M内存中的一部分必须用于系统dll的加载,那么真正剩下的也许只有400M,现在关键的地方出现了:当你使用Java创建一个线程,在JVM的内 存里也会创建一个Thread对象,但是同时也会在操作系统里创建一个真正的物理线程(参考JVM规范),操作系统会在余下的 400兆内存里创建这个物理线程,而不是在JVM的1500M的内存堆里创建。在jdk1.4里头,默认的栈大小是256KB,但是在jdk1.5里头, 默认的栈大小为1M每线程,因此,在余下400M的可用内存里边我们最多也只能创建400个可用线程。这样结论就出来了,要想创建更多的线程,你必须减少分配给JVM的最大内存。
还有一种做法是让JVM宿主在你的JNI代码里边。给出一个有关能够创建线程的最大个数的估算公式:(MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads。对于jdk1.5而言,假设操作系统保留120M内存:1.5GB JVM: (2GB-1.5Gb-120MB)/(1MB) = ~380 threads。1.0GB JVM: (2GB-1.0Gb-120MB)/(1MB) = ~880 threads。在2000/XP/2003的boot.ini里头有一个启动选项,好像是:/PAE /3G ,可以让用户进程最大内存扩充至3G,这时操作系统只能占用最多1G的虚存。那样应该可以让JVM创建更多的线程。
  • 以上就是针对Tomcat内存溢出的几种解决方案。

  • 按照上面修改完文件后启动tomcat报如下错误:进入tomcat/bin目录,执行启动的时候出现如下错误:
[root@test bin]# ./startup.sh
Cannot find ./catalina.sh
The file is absent or does not have execute permission
This file is needed to run this program
  • 解决方法:在tomcat 的bin目录下 执行这条命令chmod +x *.sh再次执行 sh catalina.sh通过,然后用sh startup.sh启动成功。如下:
[root@test bin]# chmod +x *.sh
[root@test bin]# sh catalina.sh
Using CATALINA_BASE: /usr/local/duckling/tomcat-5.5.36
Using CATALINA_HOME: /usr/local/duckling/tomcat-5.5.36
Using CATALINA_TMPDIR: /usr/local/duckling/tomcat-5.5.36/temp
Using JRE_HOME: /usr/java/jdk1.7.0
Using CLASSPATH: /usr/local/duckling/tomcat-5.5.36/bin/bootstrap.jar
Usage: catalina.sh ( commands ... )
commands:
debug Start Catalina in a debugger
debug -security Debug Catalina with a security manager
jpda start Start Catalina under JPDA debugger
run Start Catalina in the current window
run -security Start in the current window with security manager
start Start Catalina in a separate window
start -security Start in a separate window with security manager
stop Stop Catalina
stop -force Stop Catalina (followed by kill -KILL)
version What version of tomcat are you running?
[root@test bin]# sh startup.sh
Using CATALINA_BASE: /usr/local/duckling/tomcat-5.5.36
Using CATALINA_HOME: /usr/local/duckling/tomcat-5.5.36
Using CATALINA_TMPDIR: /usr/local/duckling/tomcat-5.5.36/temp
Using JRE_HOME: /usr/java/jdk1.7.0
Using CLASSPATH: /usr/local/duckling/tomcat-5.5.36/bin/bootstrap.jar
[root@test bin]#
  • 按照上述解决完问题后,可以上传成功,但是上传过程会很慢且服务器在上传时会很卡,所以需要升级服务器。
原文地址:https://www.cnblogs.com/LJing21/p/9555676.html