【每日一步】tomcat内存溢出解决方案

合集下载

解决溢出问题的方法

解决溢出问题的方法

解决溢出问题的方法
解决溢出问题的方法主要有以下几种:
1. 代码审查和优化:通过仔细审查代码,找出可能导致溢出的源头,如大量数据的处理、循环引用等。

优化这些代码段,减少内存使用。

2. 调整内存参数:调整JVM的启动参数,如-Xms和-Xmx参数,可以动态调整内存分配。

这可以帮助避免内存溢出。

3. 使用内存分析工具:使用内存分析工具(如MAT)来分析内存使用情况,找出并解决内存泄漏问题。

4. 避免大对象分配:尽量避免一次性分配大量内存,可以将大任务拆分成小任务,逐个处理。

5. 优化数据库查询:数据库查询可能导致大量数据加载到内存中,可以通过优化查询语句,减少数据加载量。

6. 升级硬件:在某些情况下,增加物理内存或升级其他硬件(如硬盘)可能有助于解决溢出问题。

7. 使用缓存技术:对于频繁使用的数据,可以使用缓存技术来减少对数据库的访问,从而减少内存使用。

8. 日志分析:仔细分析应用程序日志,查找可能导致溢出的异常或错误。

9. 垃圾回收优化:根据应用程序的特点,选择合适的垃圾回收策略,以减少内存碎片和垃圾回收开销。

10. 避免第三方软件BUG:确保使用的第三方软件没有已知的内存泄漏问题或BUG,并及时更新软件。

这些方法可以根据实际情况进行选择和应用,一般需要通过不断测试和调优来找到最适合的解决方案。

导致内存溢出原因有哪些内存溢出问题又如何解决

导致内存溢出原因有哪些内存溢出问题又如何解决

导致内存溢出原因有哪些内存溢出问题又如何解决内存溢出的原因以及解决方法1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据; 2.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收; 3.代码中存在死循环或循环产生过多重复的对象实体; 4.使用的第三方软件中的BUG; 5.启动参数内存值设定的过小内存溢出的解决方案:第一步,修改JVM启动参数,直接增加内存。

(-某m,-某m某参数一定不要忘记加。

)第二步,检查错误日志,查看“OutOfMemory”错误前是否有其它异常或错误。

第三步,对代码进行走查和分析,找出可能发生内存溢出的位置。

重点排查以下几点: 1.检查对数据库查询中,是否有一次获得全部数据的查询。

一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。

这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。

因此对于数据库查询尽量采用分页的方式查询。

2.检查代码中是否有死循环或递归调用。

3.检查是否有大循环重复产生新对象实体。

4.检查对数据库查询中,是否有一次获得全部数据的查询。

一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。

这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。

因此对于数据库查询尽量采用分页的方式查询。

5.检查Lit、MAP等集合对象是否有使用完后,未清除的问题。

Lit、MAP等集合对象会始终存有对对象的引用,使得这些对象不能被GC回收。

第四步,使用内存查看工具动态查看内存使用情况。

内存溢出的三种情况及系统配置解决方案

内存溢出的三种情况及系统配置解决方案

内存溢出的三种情况及系统配置解决方案内存溢出是指程序在运行过程中申请的内存超过了系统或者进程所能提供的上限。

导致内存溢出的原因可能是程序中存在内存泄漏、内存分配过多或者递归调用过深等。

下面将介绍三种常见的内存溢出情况及其系统配置解决方案。

1.程序内存泄漏导致内存溢出:内存泄漏指程序在运行过程中动态分配内存空间后,没有对其进行释放,导致一部分内存无法再次使用。

长时间运行的程序中,如果内存泄漏较为严重,系统可用内存会不断减少,直到最终耗尽所有内存资源。

解决方案:使用内存泄漏检测工具来检测和修复程序中的内存泄漏问题。

同时,可以考虑使用自动内存管理的编程语言,如Java和Python,在程序运行过程中自动回收未使用的内存。

2.内存分配过多导致内存溢出:解决方案:优化程序的内存使用,尽可能减小内存分配的数量和大小。

可以通过使用更高效的内存管理算法来减少内存碎片,或者使用内存池技术来提前分配一定量的内存供程序使用。

3.递归调用过深导致内存溢出:递归函数在每次调用时会将一定量的数据压入栈中,如果递归调用层数过深,栈的空间可能会超过系统的限制,从而导致内存溢出。

这种情况通常发生在没有设置递归终止条件或者递归层数过多的情况下。

解决方案:优化递归算法,设置合适的递归终止条件,避免递归调用过深。

如果无法避免使用递归算法,可以考虑使用尾递归或者迭代算法来替代递归调用,减少栈的压力。

在系统配置方面,可以采取以下措施来预防和解决内存溢出问题:1.增加系统内存容量:如果内存溢出是由于系统可用内存不足引起的,可以考虑增加系统的内存容量。

这可以通过增加物理内存条或者使用虚拟内存技术来实现。

虚拟内存技术会将部分磁盘空间用作缓存,并将一部分数据暂时存储在磁盘上,以释放内存空间。

2. 调整JVM参数:对于使用Java虚拟机(JVM)的应用程序,可以通过调整JVM的参数来控制内存的分配和管理。

例如,可以通过设置-Xmx参数来限制JVM使用的最大堆内存大小,或者通过设置-XX:MaxPermSize参数来限制JVM使用的最大持久代(PermGen)内存大小。

内存溢出的三种情况及系统配置解决方案

内存溢出的三种情况及系统配置解决方案

内存溢出的三种情况及系统配置解决方案内存溢出是指程序在运行过程中申请的内存超过了系统所分配的内存空间,导致程序崩溃或出现异常。

内存溢出通常是由于程序设计或系统配置问题引起的。

以下是三种常见的内存溢出情况及相应的系统配置解决方案。

1.单个进程占用内存过大:当一些进程在运行过程中占用的内存超过系统分配的限制时,就会导致内存溢出。

这种情况通常发生在大型应用程序或者后台服务运行时。

解决方案:-增加物理内存:在服务器或计算机中增加物理内存,以满足进程运行所需的内存空间。

-调整虚拟内存:将物理内存和虚拟内存结合使用,允许操作系统使用虚拟内存作为物理内存的扩展,从而提供更大的内存容量。

-优化应用程序:通过优化程序代码、降低内存使用、合理管理资源等方法,减少进程对内存的占用。

2.长时间运行的应用程序产生泄露:有些应用程序在长时间运行后会产生内存泄露的问题,即分配并使用内存后没有将其释放,导致内存占用逐渐增加,最终导致内存溢出。

解决方案:-使用垃圾回收机制:在一些支持垃圾回收的编程语言中,通过垃圾回收机制可以自动释放未使用的内存。

开发人员可以使用这些机制来解决内存泄露问题。

-引入内存监控工具:使用内存监控工具来检测应用程序中的内存泄露,定位并解决导致内存泄露的代码问题。

-定期重启应用程序:定期重启应用程序可以清理内存,防止内存泄露导致内存溢出。

3.大规模并发请求导致内存压力增加:在高并发的情况下,当系统同时处理大量的请求时,每个请求所占用的内存可能累积增加,导致整体内存压力增加,最终出现内存溢出。

解决方案:-加大系统负载均衡能力:通过增加负载均衡器、引入缓存机制等方式,将请求分散到多台服务器上,减少单台服务器的内存压力。

-优化数据库访问:对于一些频繁读写数据库的操作,可以通过合理的数据库设计、使用索引、缓存查询结果等方法,减少对数据库的访问,降低内存压力。

-调整服务器配置:合理设置服务器的最大并发连接数、线程池大小等参数,根据实际需求分配内存资源。

内存溢出解决方案

内存溢出解决方案

内存溢出解决方案内存溢出是指程序在运行过程中申请的内存超过了系统能够提供的最大内存空间,导致程序无法正常运行或崩溃。

内存溢出是常见的程序错误之一,解决内存溢出问题需要从以下几个方面入手:1. 内存泄漏:内存泄漏是指程序申请的内存没有被正确释放,导致内存使用量不断增加。

解决内存泄漏的方法是在程序开发过程中养成良好的编程习惯,及时释放不再使用的内存。

可以使用Java的垃圾回收机制自动回收无用内存,也可以手动管理内存,确保每次申请内存都能正确释放。

2.内存分配:合理地管理内存分配是避免内存溢出的重要方法之一、在编程过程中,应该避免过多地申请大块的内存空间,可以考虑分配多个小内存块来替代大内存块的申请。

此外,还应充分利用内存缓存,例如使用缓存池来减少频繁的内存分配和释放操作。

3.代码优化:优化代码可以减少内存的占用,并提高程序的执行效率。

可以采用以下方法进行代码优化:a.避免重复创建对象:重复创建对象会占用大量的内存空间,可以使用对象池或单例模式避免重复创建。

b.尽量使用基本数据类型:基本数据类型占用的内存空间较小,可以减少内存的使用量。

c.优化集合的使用:避免使用过多的集合对象,可以使用数组或自定义数据结构来代替。

d.内存重用:在需要重复使用内存的地方,可以考虑使用对象池来重复利用已经申请的内存空间。

4.资源管理:及时释放和关闭资源也是避免内存溢出的重要方法之一、在程序运行过程中,应该及时释放不再使用的资源,例如数据库连接、文件句柄等。

5.增加内存:如果程序中存在大量的数据处理或者内存消耗大的操作,可以考虑增加系统的内存大小。

增加内存可以提高程序的性能,并避免因内存不足而导致的溢出问题。

6. 使用内存管理工具:可以使用一些内存管理工具来检测和解决内存溢出问题。

例如,Java开发中可以使用JVM的内存分析工具来分析内存使用情况,如jmap、jhat、jconsole等。

总之,解决内存溢出问题需要从程序开发的各个方面入手,包括内存泄漏的排查和修复、合理的内存分配、代码的优化、资源的及时释放、增加内存等。

tomcat OutOfMemory错误解决方法

tomcat OutOfMemory错误解决方法

tomcat OutOfMemory错误解决方法部署应用服务到tomcat下,可能会抛出内存溢出异常,如下:Exception in thread "Timer-1" ng.OutOfMemoryError: PermGen space为了解决tomcat在大进行大并发请求时,出现内存溢出的问题,请修改tomcat的内存大小,其中分为以下两种方式:一、使用catalina.bat 等命令行方式运行的tomcat1、windows环境下,修改tomcat\bin\Catalina.bat 文件在166行左右rem Execute Java with the applicable properties ”以下每行%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS%-Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%"-Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%"-Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%在%DEBUG_OPTS% 后面添加-Xms256m -Xmx512m2、linux环境下,打开在Tomcat的安装目录的bin文件的 ./bin/catalina.sh 文件,进入编辑状态.在注释后面加上如下脚本:JAVA_OPTS='-Xms512m -Xmx1024m'JAVA_OPTS="$JAVA_OPTS -server -XX:PermSize=64M -XX:MaxPermSize=256m"或者,在echo "Using CATALINA_BASE: $CATALINA_BASE" 下添加一行echo "Using CATALINA_BASE: $CATALINA_BASE"JAVA_OPTS="-server -XX:PermSize=64M -XX:MaxPermSize=128m"echo "Using CATALINA_HOME: $CATALINA_HOME"echo "Using CATALINA_TMPDIR: $CATALINA_TMPDIR"说明:JAVA_OPTS='-Xms512m -Xmx1024m' 是设置Tomcat使用的内存的大小; -XX:PermSize=64M-XX:MaxPermSize=256m 指定类空间(用于加载类)的内存大小保存后,重新以命令行的方式运行tomcat ,即可,然后通过最后面介绍的如何观察tomcat现有内存情况的方法进行查看是否已经变更成功。

tomcat reload时内存泄漏的处理 hot deployment

tomcat reload时内存泄漏的处理 hot deployment

我做的应用是以Spring为系统的基础框架,mysql为后台数据库.在tomcat上发布后,总是不能进行热部署(reload),多次reload后,就会出OutOfMemory PermGen,为此烦恼了很久,总于下定决心找找根源.经过3天的不懈努力,小有成果,记录下来实际上下面的分析都已经没什么用了,如果你使用tomcat6.0.26及以后的版本,我所说的这些情况都已经被处理了,并且比我处理的还要多很多.可以下载tomcat6.0.26的源代码看看WebappClassLoader类的处理就成了.通过分析工具的分析(用了YourKit,以及JDK1.6/bin下的jps/jmap/jhat),发现有下面几个方面会造成memory leak.1.SystemClassLoader与WebappClassLoader加载的类相互引用,tomcat reload只是卸载WebappClassloader中的class,SystemClassLoader是不会卸载的(否则其他应用也停止了).但是WebappClassloader加载的类被SystemClassLoader引用的化,WebappClassloader中的相关类就不会被JVM进行垃圾收集目前发现2种容易产生这种leak的现象.a.在使用ng.ThreadLocal的时候很容易产生这种情况b.使用jdbc驱动,而且不是在tomcat中配置的公共连接池.则java.sql.DriverManager一定会产生这种现象ThreadLocal.set(Object),如果这个Object是WebappsClassLoader加载的,使用之后没有做ThreadLocal.set(null)或者ThreadLocal.remove(),就会产生memory leak.由于ThreadLocal实际上操作的是ng.Thread类中的ThreadLocalMap,Thread类是由SystemClassLoder加载的.而这个线程实例(main thread)在tomcat reload的时候不会销毁重建,必然就产生了SystemClassLoder中的类引用WebappsClassLoader的类.DriverManager也是由SystemClassLoder载入的,当初始化某个JDBC驱动的时候,会向DriverManager中注册该驱动,通常是***.driver,例如com.mysql.jdbc.Driver这个Driver是通过class.forName()加载的,通常也是加载到WebappClassLoader.这就出现了两个classLoader中的类的交叉引用.导致memory leak.解决办法:写一个ServletContextListener,在contextDestroyed方法中统一删除当前Thread的ThreadLocalMap中的内容.public class ApplicationCleanListener implements ServletContextListener {public void contextInitialized(ServletContextEvent event) {}public void contextDestroyed(ServletContextEvent event) {//处理ThreadLocalThreadLocalCleanUtil.clearThreadLocals();/** 如果数据故驱动是通过应用服务器(tomcat etc...)中配置的<公用>连接池,这里不需要否则必须卸载Driver** 原因: DriverManager是System classloader加载的, Driver是webappclassloader加载的,* driver保存在DriverManager中,在reload过程中,由于system* classloader不会销毁,driverManager就一直保持着对driver的引用,* driver无法卸载,与driver关联的其他类* ,例如DataSource,jdbcTemplate,dao,service....都无法卸载*/try {System.out.println("clean jdbc Driver......");for (Enumeration e = DriverManager.getDrivers(); e.hasMoreElements();) {Driver driver = (Driver) e.nextElement();if (driver.getClass().getClassLoader() == getClass().getClassLoader()) {DriverManager.deregisterDriver(driver);}}} catch (Exception e) {System.out.println("Exception cleaning up java.sql.DriverManager's driver: "+ e.getMessage());}}}/*** 这个类根据*/public class ThreadLocalCleanUtil {/*** 得到当前线程组中的所有线程description:** @return*/private static Thread[] getThreads() {ThreadGroup tg = Thread.currentThread().getThreadGroup();while (tg.getParent() != null) {tg = tg.getParent();}int threadCountGuess = tg.activeCount() + 50;Thread[] threads = new Thread[threadCountGuess];int threadCountActual = tg.enumerate(threads);while (threadCountActual == threadCountGuess) {threadCountGuess *= 2;threads = new Thread[threadCountGuess];threadCountActual = tg.enumerate(threads);}return threads;}public static void clearThreadLocals() {ClassLoader classloader = Thread.currentThread().getContextClassLoader();Thread[] threads = getThreads();try {Field threadLocalsField = Thread.class.getDeclaredField("threadLocals");threadLocalsField.setAccessible(true);Field inheritableThreadLocalsField = Thread.class.getDeclaredField("inheritableThreadLocals");inheritableThreadLocalsField.setAccessible(true);Class tlmClass = Class.forName("ng.ThreadLocal$ThreadLocalMap");Field tableField = tlmClass.getDeclaredField("table");tableField.setAccessible(true);for (int i = 0; i < threads.length; ++i) {if (threads[i] == null)continue;Object threadLocalMap = threadLocalsField.get(threads[i]);clearThreadLocalMap(threadLocalMap, tableField, classloader);threadLocalMap = inheritableThreadLocalsField.get(threads[i]);clearThreadLocalMap(threadLocalMap, tableField, classloader);}} catch (Exception e) {e.printStackTrace();}}private static void clearThreadLocalMap(Object map,Field internalTableField, ClassLoader classloader)throws NoSuchMethodException, IllegalAccessException,NoSuchFieldException, InvocationTargetException {if (map != null) {Method mapRemove = map.getClass().getDeclaredMethod("remove", new Class[] { ThreadLocal.class });mapRemove.setAccessible(true);Object[] table = (Object[]) internalTableField.get(map);int staleEntriesCount = 0;if (table != null) {for (int j = 0; j < table.length; ++j) {if (table[j] != null) {boolean remove = false;Object key = ((Reference) table[j]).get();if ((key != null)&& (key.getClass().getClassLoader() == classloader)) {remove = true;System.out.println("clean threadLocal key,class="+ key.getClass().getCanonicalName()+ ",value=" + key.toString());}Field valueField = table[j].getClass().getDeclaredField("value");valueField.setAccessible(true);Object value = valueField.get(table[j]);if ((value != null)&& (value.getClass().getClassLoader() == classloader)) {remove = true;System.out.println("clean threadLocal value,class="+ value.getClass().getCanonicalName()+ ",value=" + value.toString());}if (remove) {if (key == null)++staleEntriesCount;else {mapRemove.invoke(map, new Object[] { key });}}}}}if (staleEntriesCount > 0) {Method mapRemoveStale = map.getClass().getDeclaredMethod("expungeStaleEntries", new Class[0]);mapRemoveStale.setAccessible(true);mapRemoveStale.invoke(map, new Object[0]);}}}}2.对于使用mysql JDBC驱动的:mysql JDBC驱动会启动一个Timer Thread,这个线程在reload的时候也是无法自动销毁.因此,需要强制结束这个timer可以在上面的ApplicationCleanListener中加入如下代码:try {Class ConnectionImplClass = Thread.currentThread().getContextClassLoader().loadClass("com.mysql.jdbc.ConnectionImpl");if (ConnectionImplClass != null&& ConnectionImplClass.getClassLoader() == getClass().getClassLoader()) {System.out.println("clean mysql timer......");Field f = ConnectionImplClass.getDeclaredField("cancelTimer");f.setAccessible(true);Timer timer = (Timer) f.get(null);timer.cancel();}} catch (ng.ClassNotFoundException e1) {// do nothing} catch (Exception e) {System.out.println("Exception cleaning up MySQL cancellation timer: "+ e.getMessage());}mon-logging+log4j似乎也会导致leak,看网上有人说在ApplicationCleanListene6中加入这行代码就可以:LogFactory.release(Thread.currentThread().getContextClassLoader());我没试成功,懒得再找原因,直接换成了slf4j+logback,没有问题.据说slf4j+logback的性能还要更好.后记:tomcat-6.0.26之前的版本(我用的是tomcat-6.0.18),加入上述ApplicationCleanListener后,多次reload,不会出现outOfMemory.但要注意,第一次启动后,reload一次,内存会增加,也就是看着还是由memory Leak,但是重复reload,内存始终保持在第一次reload的大小.似乎tomcat始终保留了双WebappClassLoader.因此,配置内存要小心些,至少要保证能够load两倍的你的所有jar包的大小(当然,是指Perm的内存大小).测试过程中最好加上JVM参数-verbosegc,这样,在做GC的时候可以直观的看到class被卸载.。

内存溢出的原因有哪些怎么解决

内存溢出的原因有哪些怎么解决

内存溢出的原因有哪些怎么解决内存溢出是指程序在申请内存空间时,由于申请的内存超过了系统能够提供给该程序的最大内存限制,导致系统无法为该程序分配足够的内存空间,从而引发错误或崩溃的情况。

内存溢出的原因是多方面的,下面将介绍其中一些常见的原因以及解决方法。

1. 资源泄露:资源泄露是指程序在使用资源后没有进行正确的释放,导致这些资源一直占据着内存空间。

常见的资源包括文件句柄、数据库连接、网络连接等。

解决方法是在使用完资源后及时关闭或释放这些资源,可以使用try-finally或try-with-resources语句块来确保资源的正确关闭。

2.内存泄露:内存泄露是指程序中的对象不再被使用,但由于一些原因(如被遗忘的引用、缓存未清理等),这些对象占据了内存空间而无法被垃圾回收机制回收。

解决方法是通过合理的设计和追踪内存使用情况,及时释放不再使用的对象的引用,避免对象的循环依赖等问题。

3.递归调用:当一个方法在自身内部不断地调用自己,而没有递归终止条件,就会导致无限递归,并占用大量的内存空间。

解决方法是在递归方法内部设置递归终止条件,避免无限递归的发生。

4.大对象:当程序需要创建非常大的对象,而内存空间不足以容纳这个大对象时,就会导致内存溢出。

解决方法是将大对象分割成多个小对象,或者使用流式处理来逐步处理大对象。

5.内存泄露:如使用者创建循环的静态集合,存储了对象,然后使用完对象不进行移除,导致内存泄漏,这些创建出来的对象不能被GC回收6.使用过多的本地变量:在方法、循环体或代码快内定义大量的本地变量,或者创建了大型的数组,可能会导致栈溢出异常。

解决方法是减少本地变量的数量或者使用动态数据结构来管理数据。

7.过度使用递归:递归调用是一种常见的内存溢出问题,递归调用的深度过大,可能导致栈空间不足,从而引发栈溢出异常。

解决方法是优化递归算法,尽量将递归转换为迭代方式,或者通过增加栈空间的大小来解决。

对于内存溢出问题的解决方法,可以从以下几个方面入手:1.减少或释放无用的资源:清理不再使用的资源,避免资源泄露和内存泄露问题的发生。

内存溢出出现原因及解决方案

内存溢出出现原因及解决方案

内存溢出出现原因及解决方案篇一:内存溢出解决方案内存溢出解决方案篇二:内存溢出的三种情况及系统配置解决方案近经常有人咨询相关内存溢出的问题,在生产环境中tomcat内存设置不好很容易出现内存溢出。

造成内存原因是不一样的,当然处理方式也不一样。

这里根据平时遇到的情况和相关资料进行一个总结。

常见的一般会有下面三种情况:: Java heap space: PermGen space: unable to create new native thread.Tomcat内存溢出解决方案对于前两种情况,在应用本身没有内存泄露的情况下可以用设置tomcat jvm参数来解决。

(-Xms -Xmx -XX:PermSize -XX:MaxPermSize)最后一种可能需要调整操作系统和tomcat jvm参数同时调整才能达到目的。

第一种:是堆溢出。

在JVM中如果98%的时间是用于GC且可用的 Heap size不足2%的时候将抛出此异常信息。

没有内存泄露的情况下,调整-Xms -Xmx参数可以解决。

-Xms:初始堆大小-Xmx:最大堆大小但堆的大小受下面三方面影响:1.相关操作系统的数据模型(32-bt还是64-bit)限制;(32位系统下,一般限制在~2G;我在20XX server 系统下(物理内存:4G和6G,jdk:)测试 1612M,64为操作系统对内存无限制。

)2.系统的可用虚拟内存限制;3.系统的可用物理内存限制。

堆的大小可以使用 java -Xmx***M version 命令来测试。

支持的话会出现jdk的版本号,不支持会报错。

-Xms-Xmx一般配置成一样比较好比如set JAVA_OPTS= -Xms1024m -Xmx1024m第二种:永久保存区域溢出PermGen space的全称是Permanent Generation space,是指内存的永久保存区域。

这一部分用于存放Class和的信息,Class在被 Load的时候被放入PermGen space区域,它和和存放Instance的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。

内存溢出的解决方案

内存溢出的解决方案

内存溢出的解决方案概述内存溢出是软件开发过程中常见的问题之一。

当一个程序在执行过程中需要使用的内存超出了系统所提供的内存容量时,就会出现内存溢出的情况。

本文将介绍内存溢出的原因和常见的解决方案。

原因分析1. 内存泄漏内存泄漏是导致内存溢出的常见原因之一。

当一个对象在不再使用时,如果没有及时释放对应的内存空间,就会导致内存泄漏。

这种情况下,程序每次执行时都会分配新的内存空间,但无法释放之前分配的内存空间,最终导致内存耗尽。

2. 大对象在程序中创建大对象会占用大量的内存空间。

如果频繁地创建和销毁大对象,就会导致内存的不断分配和回收,影响程序的性能。

为了解决这个问题,可以考虑使用对象池等技术来重复利用对象,减少内存的分配和释放。

3. 递归调用递归调用是指一个方法在执行过程中又调用了自身。

如果递归调用没有正确终止条件或者终止条件设计不当,就会导致内存溢出。

在编写递归方法时,应该确保递归调用能够正确终止,避免无限的递归调用。

4. 内存申请过大有时候程序中会申请过大的内存空间,超过了系统所能提供的内存容量。

这种情况下,系统会将请求视为无效,并抛出内存溢出的异常。

为了避免这种情况,程序员应该合理评估和规划内存的使用,避免申请过大的内存空间。

解决方案1. 内存泄漏的解决方案对于内存泄漏问题,我们可以采取以下措施来解决:•合理使用引用:使用弱引用或软引用来引用那些不再使用的对象,以便在内存不足时能够自动清理这些对象。

•及时释放资源:在程序中使用完资源后,要及时将其释放。

比如关闭文件、释放数据库连接等。

•使用内存监控工具:借助内存监控工具可以监测程序运行过程中的内存使用情况,及时发现并处理内存泄漏问题。

2. 大对象的解决方案针对大对象的问题,我们可以考虑以下解决方案:•使用对象池:通过使用对象池技术,可以重复利用对象,减少内存的分配和释放,提高程序性能。

•采用延迟加载:对于大对象,可以采用延迟加载的方式,在需要使用时才进行创建,避免占用过多的内存。

内存溢出的产生原因及解决方法

内存溢出的产生原因及解决方法

内存溢出的产⽣原因及解决⽅法⼀、产⽣内存溢出的1、ng.OutofMemoryError:Java heap space2、ng.OutofMemoryError:PermGen space3、ng.OutofMemoryError:unable to create new native thread4、ng.OutofMemoryError:GC overhead limit exceeded1、Java堆空间不够,当应⽤程序申请更多的内存,⽽Java堆内存已经⽆法满⾜应⽤程序对内存的需要,将抛出这种异常。

2、Java永久代空间不够,永久代中包含类的字节码和长常量池,类的字节码加载后的信息,这和存放对象实例的堆区是不同的,⼤多数JVM的实现都不会对永久带进⾏垃圾回收,因此,只要类加载的过多就会出现这个问题。

⼀般的应⽤程序都不会产⽣这个错误,然⽽,对于Web服务器来讲,会产⽣有⼤量的JSP,JSP在运⾏时被动态的编译成Java Servlet类,然后加载到⽅法区,因此,太多的JSP的Web⼯程可能产⽣这个异常。

3、本质原因是创建了太多的线程,⽽能创建的线程数是有限制的,导致了这种异常的发⽣。

4、是在并⾏或者并发回收器在GC回收时间过长、超过98%的时间⽤来做GC并且回收了不到2%的堆内存,然后抛出这种异常进⾏提前预警,⽤来避免内存过⼩造成应⽤不能正常⼯作。

下⾯两个异常与OOM有关系,但是,⼜没有绝对关系。

1. ng.StackOverflowError …2. .SocketException: Too many open files1、是JVM的线程由于递归或者⽅法调⽤层次太多,占满了线程堆栈⽽导致的,线程堆栈默认⼤⼩为1M。

2、是由于系统对⽂件句柄的使⽤是有限制的,⽽某个应⽤程序使⽤的⽂件句柄超过了这个限制,就会导致这个问题。

⼆、产⽣原因及解决办法【情况⼀】: ng.OutOfMemoryError: Java heap space:这种是java堆内存不够,⼀个原因是真不够,另⼀个原因是程序中有死循环; 如果是java堆内存不够的话,可以通过调整JVM下⾯的配置来解决: < jvm-arg>-Xms3062m < / jvm-arg> < jvm-arg>-Xmx3062m < / jvm-arg>【情况⼆】 ng.OutOfMemoryError: GC overhead limit exceeded 【解释】:JDK6新增错误类型,当GC为释放很⼩空间占⽤⼤量时间时抛出;⼀般是因为堆太⼩,导致异常的原因,没有⾜够的内存。

Tomcat内存溢出解决办法

Tomcat内存溢出解决办法

Tomcat内存溢出解决办法使⽤Java程序从数据库中查询⼤量的数据时出现异常:ng.OutOfMemoryError: Java heap space在JVM中如果98%的时间是⽤于GC且可⽤的 Heap size 不⾜2%的时候将抛出此异常信息。

JVM堆的设置是指java程序运⾏过程中JVM可以调配使⽤的内存空间的设置.JVM在启动的时候会⾃动设置Heap size的值,其初始空间(即-Xms)是物理内存的1/64,最⼤空间(-Xmx)是物理内存的1/4。

可以利⽤JVM提供的-Xmn -Xms -Xmx等选项可进⾏设置。

解决办法:理⽅法是在myeclipse中设置TOMCAT的内存⼤⼩Tomcat是⽬前应⽤⼗分⼴泛的⼀个Java servlet container与web服务器,但ng.OutOfMemoryError与ng.OutOfMemoryError: PermGen space的异常相信真正⽤过tomcat的⼈都遇到过(⽤户量⼤,应⽤使⽤频繁等),这个异常和JVM默认划分的内存上限是128M有关,如果你的业务⾜够繁忙,128M是远远不够的,所以你可以给JVM分配上1G甚⾄更多,这样就可以避免内存溢出。

分配⽅法:1)linux下编辑tomcat的catalina.sh⽂件,在第⼀⾏的后⾯增加⼀句:JAVA_OPTS='-server -Xms256m -Xmx512m -XX:PermSize=128M -XX:MaxPermSize=256M'注意:单引号不能少,-server表⽰以server模式运⾏(运⾏效率⽐默认的client⾼很多,⾃⼰云去测试),-Xms256m是最⼩内存,-Xmx512m 是最⼤内存,其中的256与512可根据你⾃⼰的内存做相应调整,PermSize/MaxPermSize最⼩/最⼤堆⼤⼩.⼀般报内存不⾜时,都是说这个太⼩,堆空间剩余⼩于5%就会警告,建议把这个稍微设⼤⼀点,不过要视⾃⼰机器内存⼤⼩来设置,我⾃⼰的⽂件如下:#!/bin/shJAVA_OPTS='-server -Xms1024m -Xmx1024m XX:PermSize=128M -XX:MaxPermSize=256M'# -----------------------------2)windows下编辑tomcat的catalina.bat⽂件,在第⼀⾏的后⾯增加⼀句:set JAVA_OPTS=-server -Xms256m -Xmx512m -XX:PermSize=128M -XX:MaxPermSize=256M注意:没有单引号2.1)如果windows下tomcat被作为⼀种服务安装了,可通过tomcat monitor的java页进⾏配置注:Java Options中每⼀⾏的最后不能有空格。

Tomcat运行Java Web内存溢出总结

Tomcat运行Java Web内存溢出总结

Tomcat运行Java Web内存溢出总结假如JVM里运行的程序, 它的内存堆和持久存储区域的都满了,这个时候程序还想创建对象实例的话,垃圾收集器就会启动,试图释放足够的内存来创建这个对象。

这个时候假如垃圾收集器没有能力释放出足够的内存,它就会抛出OutOfMemoryError内存溢出错误。

SUN JVM 的内存管理方式: SUN的JVM是类似人类家族,也就是在一个地方创建对象,在它长久占领空间之前给它多次死亡的机会,SUN JVM会划分为: 1. 衰老的一代(Young generation),包括EDEN和2个残存物空间(动身地和目的地the From space and the To space) 2. 老一代(Old generation) 3. 永远的一代(Peanent generation) Java 虚拟机的运行时数据区普通分类如下(不一定是物理划分): 1. 堆:主要存放对象实例,线程分享 2. 栈:主要存储特定线程的办法调用状态,线程独占 3. 本地办法栈:存储本地办法的调用状态,线程独占 4. PC寄存器:学过操作系统课程的都知道,线程独占 5. 办法区:主要存储了类型信息,线程分享因此,在抛出内存溢出错误的时候,普通都会提醒内存泄露的种类,普通也都是根据区域举行划分: 1. 堆(heap)内存泄漏ng.OutOfMemoryError: Javaheap space:大家都比较认识,通过设置-Xms2048m -Xmx4096m 可以解决 2. 栈(stack)内存泄漏:当前线程运行期间维护的中间变量等信息过多,例如频繁的死循环引起stack over flow 3. 办法区(permanent heap)内存泄漏,即ng.OutOfMemoryError: PermGen space:发生的缘由和类型装载、类型卸载有挺直的关系,通过设置-XX:MaxNewSize=256m -XX:MaxPermSize=256m可以解决。

Tomcat内存溢出及线程紊乱问题研究

Tomcat内存溢出及线程紊乱问题研究

Tomcat内存溢出及线程紊乱问题研究摘要:在很多基于B/S结构的网站架构中,WEB容器内存溢出及线程紊乱问题比较隐蔽,很多时候在测试阶段并不能发现,只有在现实中大规模数据和高并发量的情况下问题才逐渐的暴露出来。

因此,在网站正式发布前代码进行走查和技术改进,并修改相关服务器软件的配置,可以在很大程度上减少此类事件的发生。

本文以Tomcat为例,对WEB容器在数据传输过程中内存溢出及线程紊乱的表现、原因及解决方案作了简要论述。

关键词:Tomcat;WEB容器;内存溢出;线程紊乱随着Internet技术的普及,各地方学校、研究所和商业单位都在积极进行基础教育资源网和资源库的建设。

然而,随着资源网使用人数的不断增加,其并发量也在急剧增长,对WEB服务器的承压性和稳定性提出了新的挑战。

然而大多数WEB容器均有内存限制,因此,在服务器没有内存还有很大空缺的情况下,WEB容器内存首先溢出,经常报“OutOfMemory”错误,并与其他因素一道引发了线程紊乱,导致应用系统的某些功能重复执行,并且引起了数据库服务器崩溃、系统越来越慢直到死机等问题。

随着互联网技术的发展,基于WEB容器大规模数据传输以及并发量的需求已经日渐突出,而数据传输效率、WEB应用服务器性能以及应用系统的稳定性等因素直接影响了数据传输的质量。

在以Tomcat为WEB容器的环境中,若以上问题处理不当,则很多时候表现为Tomcat内存溢出以及线程紊乱,造成服务器宕机,严重影响正常的网站运行。

1Tomcat内存溢出及线程紊乱的主要表现Tomcat内存溢出主要是通过系统速度、系统性能表现以及系统日志来反映的。

通过对日志文件和系统表现的分析与判断,即可断定是否为内存溢出;线程紊乱是指在Web容器中发生的线程异常的情况,其很多时候是在内存溢出之后出现的,通过对应用系统的操作日志及WEB容器的相关日志即可判断。

1.1Tomcat内存溢出主要表现1)系统的速度越来越慢,甚至出现死机的现象。

解决Tomcat应用的内存溢出问题-Tomcat-Java-JavaEye论坛

解决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占用内存最多:。

Tomcat内存溢出分析及解决方法

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第一种情况是个补充,主要存在问题就是出现在这个情况中。

Tomcat内存溢出对应解决方式

Tomcat内存溢出对应解决方式

Tomcat内存溢出对应解决⽅式1.Tomcat内存溢出的原因 ⽣产环境中Tomcat内存设置不好很容易出现内存溢出。

造成内存溢出是不⼀样的,当然处理⽅式也不⼀样。

这⾥根据平时遇到的情况和相关资料进⾏⼀个总结。

常见的⼀般会有下⾯三种情况:OutOfMemoryError: Java heap spaceOutOfMemoryError: PermGen spaceOutOfMemoryError: unable to create new native thread. Tomcat内存溢出解决⽅案 对于前两种情况,在应⽤本⾝没有内存泄露的情况下可以⽤设置tomcat jvm参数来解决。

(-Xms -Xmx -XX:PermSize -XX:MaxPermSize) 最后⼀种可能需要调整操作系统和tomcat jvm参数同时调整才能达到⽬的。

2.OutOfMemoryError 堆内存溢出a.原因分析: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:最⼤堆⼤⼩ 但堆的⼤⼩受下⾯三⽅⾯影响: 1.相关操作系统的数据模型(32-bt还是64-bit)限制;(32位系统下,⼀般限制在1.5G~2G;我在2003 server 系统下(物理内存:4G和6G,jdk:1.6)测试 1612M,64位操作系统对内存⽆限制。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

◆问题:
ng.OutOfMemoryError: Java heap space ->堆内存溢出
ng.OutOfMemoryError: PermGen space->非堆内存(永久保存区)溢出
◆说明:
◆堆(Heap)和非堆(Non-heap)内存
按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。

堆是在Java 虚拟机启动时创建的。

”“在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。

可以看出JVM主要管理两种类型的内存:堆和非堆。

简单来说堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给自己用的,所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中。

◆堆内存分配
JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。

默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx 的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。

因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。

◆非堆内存分配
JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。

◆JVM内存限制(最大值)
首先JVM内存限制于实际的最大物理内存(废话!呵呵),假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系。

简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是2GB -3GB(一般来说Windows 系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了。

◆解决方案
◆linux下
编辑tomcat的catalina.sh文件,在第一行的后面增加一句:
JAVA_OPTS='-server -Xms256m -Xmx512m -XX:PermSize=128M -XX:MaxPermSize=256M'
【注意:单引号不能少,-server表示以server模式运行】
◆windows下
◆startup.bat方式运行
编辑tomcat的catalina.bat文件,在第一行的后面增加一句:
set JAVA_OPTS=-server -Xms256m -Xmx512m -XX:PermSize=128M -XX:MaxPermSize=256M
【注:没有单引号】
◆服务方式运行
方式一:
如果windows下tomcat被作为一种服务安装了,可通过tomcat monitor 的java页进行配置
如图tomcat.bmp所示。

【注:Java Options中每一行的最后不能有空格】
方式二:
修改service.bat文件,然后执行service install tomcat_name将tomcat 安装为服务。

修改如下:
(一)
"%EXECUTABLE%" //US//%SERVICE_NAME% --JvmOptions "-XX:MaxNewSize=256m;-XX:MaxPermSize=256m;-Dcatalina.base=%CATALINA_ BASE%;-Dcatalina.home=%
CATALINA_HOME%;-Djava.endorsed.dirs=%CATALINA_HOME%\endorsed"
--StartMode jvm --StopMode jvm
(二)
"%EXECUTABLE%" //US//%SERVICE_NAME% ++JvmOptions "-Djava.io.tmpdir=%CATALINA_BASE%\temp;-Djava.util.logging.manager=org.a pache.juli.ClassLoaderLogManager;-Djava.util.logging.config.file=%CATALINA_BA SE%\conf\logging.properties" --JvmMs 256 --JvmMx 512
当然,以上各内存的设置可视自己的情况而定。

2011-08-16
wanglei
(tomcat.bmp)。

相关文档
最新文档