一次使用EclipseMemoryAnalyzer分析Tomcat内存溢出
tomcat内存溢出分析及解决方案

Tomcat内存溢出的原因在生产环境中tomcat内存设置不好很容易出现内存溢出。
造成内存溢出是不一样的,当然处理方式也不一样。
这里根据平时遇到的情况和相关资料进行一个总结。
常见的一般会有下面三种情况:1.OutOfMemoryError:Java heap space2.OutOfMemoryError:PermGen space3.OutOfMemoryError:unable to create new native thread.Tomcat内存溢出解决方案对于前两种情况,在应用本身没有内存泄露的情况下可以用设置tomcat jvm参数来解决。
(-Xms -Xmx -XX:PermSize -XX:MaxPermSize)最后一种可能需要调整操作系统和tomcat jvm参数同时调整才能达到目的。
第一种:是堆溢出。
原因分析:JVM堆的设置是指java程序运行过程中JVM可以调配使用的内存空间的设置.JVM在启动的时候会自动设置Heap size的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。
可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置。
Heap size 的大小是Young Generation 和Tenured Generaion 之和。
在JVM中如果98%的时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息。
Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值。
没有内存泄露的情况下,调整-Xms -Xmx参数可以解决。
-Xms:初始堆大小-Xmx:最大堆大小但堆的大小受下面三方面影响:1.相关操作系统的数据模型(32-bt还是64-bit)限制;(32位系统下,一般限制在1.5G~2G;我在2003 server 系统下(物理内存:4G和6G,jdk:1.6)测试1612M,64位操作系统对内存无限制。
JVM:全面理解线上服务器内存溢出(OOM)问题处理方案

JVM:全面理解线上服务器内存溢出(OOM)问题处理方案在现代应用程序开发中,内存管理是一个非常重要的方面。
虽然现代计算机中的内存容量已经非常大,但是在高负载和大数据量的情况下,仍然可能遇到内存溢出(OOM)。
内存溢出是指程序在运行过程中使用的内存量超过了系统设置的限制,导致程序运行失败。
这对生产环境的服务器是非常严重的,因为它可能导致服务器崩溃,进而影响用户体验。
JVM是Java程序的运行时环境,一旦发生线上服务器内存溢出问题,我们需要处理这个问题的步骤如下:一、分析内存溢出错误日志JVM在发生内存溢出时会产生错误日志,这些日志信息提供了非常有用的信息,有助于分析问题的原因。
在分析日志的时候,需要关注以下几个方面:1.错误信息:内存溢出错误的类型,以及导致错误的相关代码。
2.内存使用情况:分析 JVM 中各个方面的内存使用情况,例如堆内存、非堆内存、元数据内存等。
3.内存泄漏:分析可能导致内存泄漏的代码。
二、调整 JVM 参数JVM提供了很多可供调整的参数,通过调整这些参数可以使JVM 在运行过程中使用更少的内存。
例如,调整堆大小、非堆大小、GC策略等。
在选择适当的 JVM 参数时,可以参考JVM 官方文档中提供的建议参数。
但是,需要注意的是,不要随意调整JVM 参数,否则可能会导致系统运行状况更糟糕。
三、检查代码中的内存泄漏内存泄漏是指程序中申请的内存没有被及时释放,导致内存空间被占用,进而导致内存溢出。
在 Java 中,由于 Java 自带GC,因此内存泄漏的问题相对较少,但仍然有可能发生。
在排查内存泄漏问题时,可以使用 Java 堆栈跟踪工具,例如Eclipse Memory Analyzer (MAT) 来分析堆中的对象和数据,从而快速定位内存泄漏的原因。
四、优化代码优化代码是解决内存溢出问题的最重要的一步。
通过优化代码,减少对内存的消耗,可以有效地防止内存溢出问题。
优化代码的方法有很多,例如,使用缓存、避免频繁的创建多个对象、使用数据结构等。
Tomcat内存溢出分析及解决方法

Tomcat内存溢出分析及解决方法Tomcat内存溢出分析及解决方法JVM管理两种类型的内存,堆和非堆。
堆是给开发人员用的上面说的就是,是在JVM启动时创建;非堆是留给JVM自己用的,用来存放类的信息的。
它和堆不同,运行期内GC不会释放空间。
一、内存溢出类型1、ng.OutOfMemoryError: PermGen spaceJVM管理两种类型的内存,堆和非堆。
堆是给开发人员用的上面说的就是,是在JVM启动时创建;非堆是留给JVM自己用的,用来存放类的信息的。
它和堆不同,运行期内GC不会释放空间。
如果web app用了大量的第三方jar或者应用有太多的class文件而恰好MaxPermSize设置较小,超出了也会导致这块内存的占用过多造成溢出,或者tomcat热部署时侯不会清理前面加载的环境,只会将context更改为新部署的,非堆存的内容就会越来越多。
PermGen space的全称是Permanent Generation space,是指内存的永久保存区域,这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中,它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的应用中有很CLASS的话,就很可能出现PermGen space错误,这种错误常见在web服务器对JSP进行pre compile的时候。
如果你的WEB APP下都用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。
一个最佳的配置例子:(经过本人验证,自从用此配置之后,再未出现过tomcat死掉的情况)set JAVA_OPTS=-Xms800m -Xmx800m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m在linux下在tomcathome/conf/catalina.sh中加上如标红所示的一句代码:可以增加tomcat jvm 的内存,这样就不容易出现内存溢出的现象了!# ----- Execute The Requested Command -----------------------------------------JAVA_OPTS="-server -Xms512m -Xmx2048m -XX:PermSize=128m -XX:MaxNewSize=256m -XX:MaxPermSize=256m"# Bugzilla 37848: only output this if we have a TTY2、ng.OutOfMemoryError: Javaheap space第一种情况是个补充,主要存在问题就是出现在这个情况中。
eclipse经常卡死、反应慢、内存溢出的解决方案

eclipse经常卡死、反应慢、内存溢出的解决⽅案开发过程中经常遇到eclipse卡死的问题,所以特此通过⽹上查找和实践总结了以下解决⽅法:1.修改eclipse内存找到eclipse的安装⽬录,在⽬录下有个eclipse.ini⽂件,打开添加如下配置(我的电脑内存3G,可以参考下⾯配置做调整,不⽤太⾼)-Xms1024m-Xmx2048m-XX:MaxPermSize=1024M-XX:-UseGCOverheadLimit2.修改JDK的使⽤内存打开eclipse,window->preference->Java->Installed JREs,选中使⽤的jdk然后点击右侧的edit,在Default VM Arguments中输⼊以下值-Xms512m -Xmx512m -XX:MaxNewSize=512m -XX:MaxPermSize=512m3.取消⼀些不必要的插件启动window->preference->General->Startup and Shutdown ,将插件的启动全部取消4.取消⾃动检测,修改⼀些jsp、html等⽂件保存时会⾃动检测导致eclipse卡掉,所以全部取消掉window->preference->Validation5.关闭拼写检查window->preference->General->Editors->Text Editors->Spelling ,取消掉Enable spelling checking6.取消⾃动编译,java类修改时就不会⾃动编译了Project->Build Automatically 前⾯的勾取消掉7.修改jsp、html等容易卡顿⽂件的编辑⼯具window->preference->General->Editors->File Associations ,选择*.html,下⾯的aSSociated editors 选择Text Editor...然后点击右侧的Default,继续FileTypes选择*.jsp,后续操作⼀样,都改为默认Text Editor...8.修改打开链接的快捷键,将ctrl改为alt9.杜绝jar包访问⽹络window->preference->Java->Installed JREs 选择使⽤的jre并点击右侧的Edit在编辑框中的JRE system libraries找到jre的rt.jar和charsets.jar,将其中的Javadoc location通过右侧的remove按钮置为none.10.代码修改时不重启tomcat在eclipse中打开⽂件server.xml,将reloadable改为false,添加crossContext="true",这样就能进⾏热启动了,注意需要⽤debug模式启动。
memoryanalyzer 用法

一、什么是memoryanalyzer?Memoryanalyzer 是一个用于分析 Java 程序在运行过程中的内存使用情况的工具。
它可以帮助开发人员识别和解决内存泄漏和内存溢出等问题,以提高程序的性能和稳定性。
二、 memoryanalyzer 的主要功能1. 内存快照分析:通过获取 Java 程序的内存快照,memoryanalyzer 可以帮助开发人员查看程序在不同时间点的内存使用情况,以便分析内存泄漏和内存溢出等问题。
2. 内存泄漏检测:memoryanalyzer 可以帮助开发人员识别程序中存在的内存泄漏问题,从而及时解决这些问题,提高程序的内存利用率和性能。
3. 内存溢出分析:通过分析程序在运行过程中出现的内存溢出情况,memoryanalyzer 可以帮助开发人员定位问题代码,以便进行优化和改进。
三、 memoryanalyzer 的使用方法1. 获取内存快照:使用 memoryanalyzer 工具可以获取 Java 程序的内存快照。
可以使用命令行工具或者图形界面工具来获取内存快照。
2. 分析内存快照:获取内存快照后,可以使用 memoryanalyzer 工具来对内存快照进行分析,以查看程序在不同时间点的内存使用情况,并识别可能存在的内存泄漏和内存溢出问题。
3. 解决内存问题:根据 memoryanalyzer 的分析结果,开发人员可以及时解决程序中存在的内存问题,从而提高程序的性能和稳定性。
四、 memoryanalyzer 的优点和局限性1. 优点:memoryanalyzer 可以帮助开发人员快速定位并解决程序中的内存问题,提高程序的性能和稳定性。
2. 局限性:memoryanalyzer 在使用过程中需要一定的学习成本,而且对于庞大的内存快照的分析可能会消耗较多的时间和计算资源。
五、总结通过以上的介绍,我们可以看到,memoryanalyzer 是一个功能强大的工具,可以帮助开发人员分析 Java 程序的内存使用情况,并解决程序中可能存在的内存问题。
一次Java内存溢出异常的分析过程

一次Java内存溢出异常的分析过程2011-08-28 00:00中国IT实验室佚名字号:A+|A-前些天,服务器上一个服务跑了一个多月突然当掉了。
看了下日志,程序抛出了ng.OutOfMemoryError,之前也出现过同样的错误,服务跑了三个月内存溢出。
出现这个异常,初步判断是程序有内存泄漏,接下来需要利用一些工具来分析具体原因。
首先使用jdk自带的工具jmap转储(dump)java内存堆数据到本地文件中。
jmap转储(dump)命令格式如下:jmap -dump:表示dump选项,表示需要dump的java应用程序的进程IDdump-options可以有以下三种参数,参数之间用逗号隔开:live,只dump活动的object,如果没有指定,表示dump所有objectformat=b,字节流格式file=,是转储文件的保存路径下面是dump命令的一个例子:jmap -dump:format=b,file=heap.bin 8023dump完成后,用Eclipse Memory Analyzer打开转储文件进行分析。
Eclipse Memory Analyzer是一个java内存堆转储文件分析工具,可以生成内存分析报告(包括内存泄露Leak Suspects )。
下面是分析完成后查看Top Consumers所看到的图表:看到这两张图表,问题就比较明朗了。
berkeley db中的数据结点com.sleepycat.je.tree.BIN占用了大量内存,导致内存溢出了。
为了提高访问效率,berkeley db会缓存大量的结点,缓存大小限制可以在EnvironmentConfig设置,默认为jvm 内存大小限制的60%。
而这个应用程序中使用了5个EnvironmentImpl,并且都未单独设置缓存大小,总的缓存限制为jvm内存限制的300%(图表中BIN结点已经占用了94.55%的内存),远远超出java的内存限制。
使用MAT工具进行内存溢出定位及分析
内存溢出监控及分析问题所在一、内存溢出&内存泄漏的名词解释内存溢出(out of memory):就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。
内存泄露(memory leak):是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。
二、何时会抛出内存溢出错误何时会抛出OutOfMemoryException,并不是内存被耗空的时候才抛出∙JVM98%的时间都花费在内存回收∙每次回收的内存小于2%满足这两个条件将触发OutOfMemoryException,这将会留给系统一个微小的间隙以做一些Down之前的操作,比如手动打印Heap Dump。
Q:为什么崩溃前垃圾回收的时间越来越长?A:根据内存模型和垃圾回收算法,垃圾回收分两部分:内存标记、清除(复制),标记部分只要内存大小固定时间是不变的,变的是复制部分,因为每次垃圾回收都有一些回收不掉的内存,所以增加了复制量,导致时间延长。
所以,垃圾回收的时间也可以作为判断内存泄漏的依据Q:为什么Full GC的次数越来越多?A:因此内存的积累,逐渐耗尽了年老代的内存,导致新对象分配没有更多的空间,从而导致频繁的垃圾回收Q:为什么年老代占用的内存越来越大?A:因为年轻代的内存无法被回收,越来越多地被Copy到年老代三、内存溢出的一些现象现象1、后台日志会报错- Out of Memory当Java程序申请内存,超出VM可分配内存的时候,VM首先可能会垃圾回收(GC),如果GC完还是不够,或者申请的直接超够VM可能有的,就会抛出内存溢出异常。
从VM规范中我们可以得到,以下几种异常:ng.StackOverflowError:(很少)ng.OutOfMemoryError:heap space(比较常见)ng.OutOfMemoryError: PermGen space (经常出现)ng.OutOfMemoryError: GC overhead limit exceeded(某项操作使用大量内存时发生)现象2、通过loadrunner的windows监控图的部分指标走势能猜测是否发生内存泄漏。
使用MemoryAnalyzertoolMAT分析内存泄漏
使用Memory Analyzer tool(MAT)分析内存泄漏(一)前言在平时工作过程中,有时会遇到OutOfMemoryError,我们知道遇到Error一般表明程序存在着严重问题,可能是灾难性的。
所以找出是什么原因造成OutOfMemoryError非常重要。
现在向大家引荐Eclipse Memory Analyzer tool(MAT),来化解我们遇到的难题。
如未说明,本文均使用Java 5.0 on Windows XP SP3环境。
为什么用MAT之前的观点,我认为使用实时profiling/monitoring之类的工具,用一种非常实时的方式来分析哪里存在内存泄漏是很正确的。
年初使用了某profiler工具测试消息中间件中存在的内存泄漏,发现在吞吐量很高的时候profiler工具自己也无法响应,这让人很头痛。
后来了解到这样的工具本身就要消耗性能,且在某些条件下还发现不了泄漏。
所以,分析离线数据就非常重要了,MAT正是这样一款工具。
为何会内存溢出我们知道JVM根据generation(代)来进行GC,根据下图所示,一共被分为young generation(年轻代)、tenured generation(老年代)、permanent generation(永久代, perm gen),perm gen(或称Non-Heap 非堆)是个异类,稍后会讲到。
注意,heap空间不包括perm gen。
绝大多数的对象都在young generation被分配,也在young generation被收回,当young generation的空间被填满,GC会进行minor collection(次回收),这次回收不涉及到heap中的其他generation,minor collection根据weak generational hypothesis(弱年代假设)来假设young generation中大量的对象都是垃圾需要回收,minor collection的过程会非常快。
使用Memory Analyzer tool(MAT)分析内存泄漏(二)
使用Memory Analyzer tool(MAT)分析内存泄漏(二)前言的前言写blog就是好,在大前提下可以想说什么写什么,不像投稿那么字字斟酌。
上周末回了趟成都办事,所以本文来迟了。
K117从达州经由达成线往成都方向走的时候,发现铁路边有条河,尽管我现在也不知道其名字,但已被其深深的陶醉。
河很宽且水流平缓,河边山丘森林密布,民房星星点点的分布在河边,河里偶尔些小船。
当时我就在想,在这里生活是多么的惬意,夏天还可以下去畅游一番,闲来无事也可垂钓。
唉,越来越讨厌北漂了。
前言在使用Memory Analyzer tool(MAT)分析内存泄漏(一)中,我介绍了内存泄漏的前因后果。
在本文中,将介绍MAT如何根据heap dump分析泄漏根源。
由于测试范例可能过于简单,很容易找出问题,但我期待借此举一反三。
一开始不得不说说ClassLoader,本质上,它的工作就是把磁盘上的类文件读入内存,然后调用ng.ClassLoader.defineClass方法告诉系统把内存镜像处理成合法的字节码。
Java 提供了抽象类ClassLoader,所有用户自定义类装载器都实例化自ClassLoader的子类。
system class loader在没有指定装载器的情况下默认装载用户类,在Sun Java 1.5中既uncher$AppClassLoader。
更详细的内容请参看下面的资料。
准备heap dump请看下面的Pilot类,没啥特殊的。
/*** Pilot class* @author rosen jiang*/package org.rosenjiang.bo;public class Pilot{String name;int age;public Pilot(String a, int b){name = a;age = b;}}然后再看OOMHeapTest类,它是如何撑破heap dump的。
解决Tomcat应用的内存溢出问题-Tomcat-Java-JavaEye论坛
解决Tomcat应用的内存溢出问题-Tomcat-Java-JavaEye论坛维护一个老系统,发现有ng.OutOfMemoryError: Java heap space的情况,内存溢出,以下是大致的解决过程:1.安装JProfiler,并配置成监控本地的tomcat2.修改catalina.bat,添加参数: set JAVA_OPTS= -Xms768m -Xmx1024m -verbose:gc -Xloggc:../logs/gclog.log -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution -XX:+HeapDumpOnOutOfMemoryError %JAVA_OPTS%3.使用JProfiler在Tomcat的bin目录下创建的启动脚本startup_jprofiler.bat重启tomcat4.运行JProfiler观察内存状况,未发现问题5.第二天突然发现T omcat再次出现内存溢出,Tomcat的bin目录下自动生成了java_pid107932.hprof文件,将此文件下载到本地,以便分析。
6.下载Memory Analyzer工具,然后打开该hprof文件进行分析,发现是SmartUpload的问题:com.jspsmart.upload.Files占用内存1G多。
7.用Apache的上传组件替换掉smartupload,目前没有发现问题附上Memory Analyzer分析的图片:Leak Suspects显示,有一个东西占了1007.9M的内存:点击底部的Details链接,发现是com.jspsmart.upload.Files占用内存最多:。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
前言
在平时开发、测试过程中、甚至是生产环境中,有时会遇到OutOfMemoryError,Java堆溢出了,这表明程序有严重的问题。
我们需要找造成OutOfMemoryError原因。
一般有两种情况:
1、内存泄露,对象已经死了,无法通过垃圾收集器进行自动回收,通过找出泄露的代码位置和原因,才好确定解决方案;
2、内存溢出,内存中的对象都还必须存活着,这说明Java堆分配空间不足,检查堆设置大小(-Xmx与-Xms),检查代码是否存在对象生命周期太长、持有状态时间过长的情况。
以上是处理Java堆问题的思路,具体是怎么进行分析,这里介绍的是使用Eclipse Memory Analyzer tool(MAT)工具分析的过程。
生成dump文件
通过jvm参数--XX:-HeapDumpOnOutOfMemoryError可以让JVM在出现内存溢出是Dump出当前的内存转储快照;
或者,用jmap生产dump文件,win通过任务管理器查看tomcat的进程pid,linux用ps命令查看进程pid,然后用jmap命令(Java5:jmap -heap:format=b <pid>;Java6:jmap -dump:format=b,file= <pid>)。
我这里使用的是,我一生产环境项目,运行一段时间大概3周的样子,就会报OutOfMemoryError。
(ps:这个项目出现这种情况已经有好长一段时间了,我们之前的做法是定期的重启tomcat,没有去分析它的原因。
)JDK64位主要参数:
-Xmx3078M -Xms3078M -XX:PermSize=1024M -XX:MaxPermSize=1024M,内存还是蛮大的。
MAT安装与介绍
下载地址:。
通过MAT打开dump出来的内存文件,打开后如下图:
从上图可以看到它的大部分功能。
1. Histogram可以列出内存中的对象,对象的个数以及大小。
2. Dominator Tree可以列出那个线程,以及线程下面的那些对象占用的空间。
consumers通过图形列出最大的object。
Suspects通过MA自动分析泄漏的原因。
Histogram如下图:
Objects:类的对象的数量。
Shallow size:就是对象本身占用内存的大小,不包含对其他对象的引用,也就是对象头加成员变量(不是成员变量的值)的总和。
Retained size:是该对象自己的shallow size,加上从该对象能直接或间接访问到对象的shallow size之和。
换句话说,retained size是该对象被GC之后所能回收到内存的总和。
我们发现ThreadLocal和类的对象占用了很多空间。
Dominator Tree如下图:
我们发现quartz的定时器的工作线程(10个)占了很多的内存空间
Top consumers如下图:
这里显示了内存中最大的对象有哪些,他们对应的类是哪些,类加载器classloader是哪些。
有些时候,我们在这里就可以看到代码泄露的位置。
Leak Suspects如下图:
从那个饼图,该图深色区域被怀疑有内存泄漏,可以发现整个heap才250M内存,深色区域就占了34%。
后面的描述,告诉我们quartz线程占用了大量内存,并指出system class loader加载的""实例的内存中聚集(消耗空间),并建议用关键字""进行检查。
所以,MAT通过简单的报告就说明了问题所在。
通过Leak Suspects的Problem Suspect 1点击【Details »】,
如下图如下图所示的上下文菜单中选择 List objects -> with outgoning references, 查看ThreadLocal都应用了些什么对象。
现在看到ThreadLocal中引用的对象如下图:
是dao对象
ps:该dao对象包含一个轻量级的ORM关系内容,所以Retained size比较大。
下面继续查看dao的gc ROOT
如下图所示的上下文菜单中选择 Path To GC Roots -> exclude weak references, 过滤掉弱引用,因为在这里弱引用不是引起问题的关键。
从下图中,可以看到在中保存了daos的引用。
所以可以得出是是因为定时器在运行的过程中持有大量的Daos对象应起了内存泄露。
为什么会有那么多的Daos呢,Daos不是一个无状态的单例的、可以重用的吗?继续查看spring配置文件发现Daos的bean 配置成scope="prototype",导致定时任务又是每次调用都生产新的Daos实例。
由于是Daos是无状态的,修改为单例的,问题解决。
以上是通过MAT分析Tomcat应用程序,找到内存泄露的原因,并解决。