tomcat 内存溢出万恶OOM

时间:2022-04-27 16:21:35

因为项目实施压力测试,开始关注一些tomcat调优与jvm的调优。这里对最近的一些知识点做个总结


万恶的OOM

1、第一种OutOfMemoryError:PermGen space

这种溢出 主要是因为tomcat加载jar包和class文件过多,而加载内存空间不够用抛出的异常。 解决方案 一、增加java虚拟机中的XX:PermSize和XX:MaxPermSize参数的大小,其中XX:PermSize是初始永久保存区域大小, XX:MaxPermSize是最大永久保存区域大小。 二、清理应用程序中web-inf/lib下的jar,如果tomcat部署了多个应用,很多应用都使用了相同的jar,可以将共同的jar移到tomcat共同的lib下,减少类的重复加载。 使用方式。在tomcat 中新建一个my-lib文件夹,拷贝所有的jar 进去,然后再catalina.properties  文件中增加配置shared.loader=${catalina.base}/my-lib,${catalina.base}/my-lib/*.jar (个人比较推荐这种。第一种简单粗暴。第二种更有针对性。细腻)

2、错误提示:java.lang.OutOfMemoryError:Java heap space

这种主要是运行内存溢出。应用在运行期间进行了大量的创建对象。

一、检查应用代码,去掉不必要的对象的创建(单例模式)。

      题外话,之前去别的项目组做支持,项目中用到了redis缓存。我简单介绍一下他们的使用方式。在需要缓存的地方创建redis工厂然后拿到redis实例对象,进行操作,使用完。关闭销毁reidis实例。相当于创建一个工厂只做了一件事情就销毁了工厂。而不是一个工厂做很多的事情。

二、增加java虚拟机的运行内存。增加Java虚拟机中Xms(初始堆大小)和Xmx(最大堆大小)参数的大小。如:set
JAVA_OPTS= -Xms512m -Xmx1024m

3、OutOfMemoryError:unable to create new native thread

这种异常的出现,是因为没有更多的内存来让我们创建线程。分析原因

设定一个场景 我们的服务器只有2G内存。而我们tomcat在配置的时候设置了最大1.5G内存。还剩下500M的内存给我们的系统,

系统资源加载系统文件也会占去300M内存。那么我们剩下的内存只有200M,在jdk1.5里头,默认的栈大小为1M每线程,

因此,在余下200M的可用内存里边我们最多也只能创建200个可用线程。当我们创建的线程超出200个时候就会抛出这个歌异常

一、应用层面优化,分析发生内存溢出时进程中到底都有什么样的线程,这些线程是否是应该存在的,是否可以通过优化来降低线程数。

二、设置tomcat配置参数Xss属性,代表着每条线程的内存大小 -Xss 128K,线程栈内存大小设置为128k

三、调整jvm内存让出更多内存。我们把jvm最大内存设置到1G。这样我们就可以多出500M,也就是500条线程可用



题外怎么计算我们服务器最大的线程数量。

创建最大的线程数量,受俩个因素的影响。

一、系统因素 Windows系统和linux系统 能支持的最大线程数量是不一样的。

二、jvm虚拟机影响 在java语言里, 当你创建一个线程的时候,虚拟机会在JVM内存创建一个Thread对象同时创建一个操作系统线程,而这个系统线程的内存用的不是JVMMemory,而是系统中剩下的内存(MaxProcessMemory - JVMMemory - ReservedOsMemory)。


参考

(MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads

MaxProcessMemory 指的是一个进程的最大内存
JVMMemory         JVM内存
ReservedOsMemory  保留的操作系统内存
ThreadStackSize      线程栈的大小