一般来说溢出分2种,一种是heap堆溢出,一种是本地native溢出
但对于WAS来说,大部分都是heap堆溢出,这个跟IBM JDK的实现有关(IBM的比较另类)
堆溢出也分为大对象,内存碎片等。
大对象相对好办一些,只要分析heapdump,结合应用日志,找到是哪个类(一般都是arraylist,vector等),限制前台操作条件和后台访问数据库的SQL就可以。
但是内存碎片稍麻烦点,
这也和IBM的JDK实现有关系。
一般的解决办法就是加xk,xp参数。网上发现一篇文章写的比较全面,转贴如下
内容提要:
用户在使用WebSphere Application Server(以下简称WAS)运行自己应用的时候经常会碰到Out OfMemory的问题(简称OOM问题),其中很大一部分的情况是Java堆空间碎片问题引起的OOM问题。IBM JDK1.4.2的版本中JDK对GC的行为做出了一定的改进。其中一些JDK参数的引进可以改善Java堆空间的碎片问题。
本文首先会给出IBM JDK1.4.2中对于K簇(k-cluster)和P簇(p-cluster)工作模式的解释。然后在此基础上介绍JDK1.4.2为解决碎片问题采取的新算法。最后,给出WAS中为改善Java堆空间碎片问题使用的JDK运行参数。
正文:
一、K簇和P簇
在Java堆空间中分配的内存对象通常是可以移动,如果垃圾回收程序(garbagecollector)决定重新序列化堆空间的时候,可以四处移动这些对象。然而,有些对象永远或者临时无法移动。这些固定不动的对象就是常说的pin对象(pinnedobject)。
在IBM JDK 1.4.2中,垃圾回收程序首先会分配一个K簇作为堆空间底部的第一个对象。K簇是专门用来存储“类块”(classblock)的区域。K簇可以容纳1280个类块条目。每个类块的大小是256个字节。紧接着垃圾回收程序会分配一个P簇作为堆空间中的第2个对象。P簇是用来存储pin对象的区域。第一个P簇的默认大小为16KB。
当K簇满了的情况下,垃圾回收程序在P簇中继续分配类块。当P簇满了的情况下,垃圾回收程序会分配一个大小为2KB的新P簇。由于这些新的P簇可以被分配到任何地方而且又不能被移动,这就造成了碎片的问题。
用户在使用WebSphere Application Server(以下简称WAS)运行自己应用的时候经常会碰到Out OfMemory的问题(简称OOM问题),其中很大一部分的情况是Java堆空间碎片问题引起的OOM问题。IBM JDK1.4.2的版本中JDK对GC的行为做出了一定的改进。其中一些JDK参数的引进可以改善Java堆空间的碎片问题。
本文首先会给出IBM JDK1.4.2中对于K簇(k-cluster)和P簇(p-cluster)工作模式的解释。然后在此基础上介绍JDK1.4.2为解决碎片问题采取的新算法。最后,给出WAS中为改善Java堆空间碎片问题使用的JDK运行参数。
正文:
一、K簇和P簇
在Java堆空间中分配的内存对象通常是可以移动,如果垃圾回收程序(garbagecollector)决定重新序列化堆空间的时候,可以四处移动这些对象。然而,有些对象永远或者临时无法移动。这些固定不动的对象就是常说的pin对象(pinnedobject)。
在IBM JDK 1.4.2中,垃圾回收程序首先会分配一个K簇作为堆空间底部的第一个对象。K簇是专门用来存储“类块”(classblock)的区域。K簇可以容纳1280个类块条目。每个类块的大小是256个字节。紧接着垃圾回收程序会分配一个P簇作为堆空间中的第2个对象。P簇是用来存储pin对象的区域。第一个P簇的默认大小为16KB。
当K簇满了的情况下,垃圾回收程序在P簇中继续分配类块。当P簇满了的情况下,垃圾回收程序会分配一个大小为2KB的新P簇。由于这些新的P簇可以被分配到任何地方而且又不能被移动,这就造成了碎片的问题。
二、pinnedFreeList算法
为了解决这些问题,IBM JDK1.4.2版本中起用了pinnedFreeList来改变P簇的分配方法。方法的关键是在每一次GC(garbagecollection)后,垃圾回收程序从未分配列表的底部分配一些存储区并把它们串到pinnedFreeList上。分配P簇的请求将从pinnedFreeList分配空间,而其他分配内存的请求将从堆的未分配列表上分配。无论堆的未分配列表或者pinnedFreeList被耗尽,垃圾回收程序都会造成一次分配失败并且引起GC。这种方法确保所有的P簇被分配在堆空间尽可能低的位置。
垃圾回收程序按照如下的算法确定给pinnedFreeList分配多少存储空间:
● 初始分配的空间是50KB
● 如果不是初始分配并且pinnedFreeList为空,那么垃圾回收程序会比较50KB和从上一次GC到现在总共分配P簇大小5倍的数值,按照较大的数值分配
● 如果不是初始分配并且pinnedFreeList不为空,那么垃圾回收程序会比较P簇溢出设定值(默认为2K)和从上一次GC到现在总共分配P簇大小5倍的数值,按照较大的数值分配
这一算法在应用需要加载很多类的情况下会增大pinnedFreeList的大小。这样可以避免由于pinnedFreeList耗尽引起的分配失败。同时算法在分配很少P簇的情况下会减少pinnedFreeList的大小。这样可以避免pinnedFreeList占用过多的堆空间。
buildPinnedFreeList函数利用上面的算法构建pinnedFreeList。这个函数在如下地方会被调用:
● 在初始化簇(initializeClusters)时
● 在堆空间扩展(expandHeap)结束时
● 在gc0_locked结束时
垃圾回收程序通过调用nextPinnedCluster函数在pinnedFreeList中分配P簇。这个函数的工作方式类似于nextTLH工作方式:总是从pinnedFreeList获取下一个空的块。如果pinnedFreeList空了,会产生manageAllocFailure。
在realObjCAlloc里,如果在P簇中没有空间了,垃圾回收程序就会调用nextPinnedCluster函数分配一个新的P簇。
在初始化簇(initializeClusters)时,垃圾回收程序调用nextPinnedCluster,nextPinnedCluster会分配一个50K大小的初始P簇,因为pinnedFreeList中唯一的空余块的大小是50K。空余块的大小等于50K是因为pinnedFreeList在初始状态下被设置为50K。
为了解决这些问题,IBM JDK1.4.2版本中起用了pinnedFreeList来改变P簇的分配方法。方法的关键是在每一次GC(garbagecollection)后,垃圾回收程序从未分配列表的底部分配一些存储区并把它们串到pinnedFreeList上。分配P簇的请求将从pinnedFreeList分配空间,而其他分配内存的请求将从堆的未分配列表上分配。无论堆的未分配列表或者pinnedFreeList被耗尽,垃圾回收程序都会造成一次分配失败并且引起GC。这种方法确保所有的P簇被分配在堆空间尽可能低的位置。
垃圾回收程序按照如下的算法确定给pinnedFreeList分配多少存储空间:
● 初始分配的空间是50KB
● 如果不是初始分配并且pinnedFreeList为空,那么垃圾回收程序会比较50KB和从上一次GC到现在总共分配P簇大小5倍的数值,按照较大的数值分配
● 如果不是初始分配并且pinnedFreeList不为空,那么垃圾回收程序会比较P簇溢出设定值(默认为2K)和从上一次GC到现在总共分配P簇大小5倍的数值,按照较大的数值分配
这一算法在应用需要加载很多类的情况下会增大pinnedFreeList的大小。这样可以避免由于pinnedFreeList耗尽引起的分配失败。同时算法在分配很少P簇的情况下会减少pinnedFreeList的大小。这样可以避免pinnedFreeList占用过多的堆空间。
buildPinnedFreeList函数利用上面的算法构建pinnedFreeList。这个函数在如下地方会被调用:
● 在初始化簇(initializeClusters)时
● 在堆空间扩展(expandHeap)结束时
● 在gc0_locked结束时
垃圾回收程序通过调用nextPinnedCluster函数在pinnedFreeList中分配P簇。这个函数的工作方式类似于nextTLH工作方式:总是从pinnedFreeList获取下一个空的块。如果pinnedFreeList空了,会产生manageAllocFailure。
在realObjCAlloc里,如果在P簇中没有空间了,垃圾回收程序就会调用nextPinnedCluster函数分配一个新的P簇。
在初始化簇(initializeClusters)时,垃圾回收程序调用nextPinnedCluster,nextPinnedCluster会分配一个50K大小的初始P簇,因为pinnedFreeList中唯一的空余块的大小是50K。空余块的大小等于50K是因为pinnedFreeList在初始状态下被设置为50K。
三、调整Java运行参数
对于一个大的Java应用,比如:WAS,默认的K簇可能不足以分配所有的类块。在IBM JDK1.4.2版本中,可以通过使用-Xk和-Xp命令行参数来设定K簇和P簇的大小,例如:
-Xknnnn
其中nnnn代表K簇中可以容纳的类块的最大数目。通过添加Java的运行是参数-Dibm.dg.trc.print=st_verify 可以在GC的详细信息中得到合适nnnn的值,例如:
<GC(VFY-SUM):pinned=4265(classes=3955/freeclasses=0) dosed=10388 movable=1233792free=5658>
pinned和classes的数值可以为-Xk的正确数值提供参考。一般推荐使用classes(3955)数值的110%左右,所以在这个例子中-Xk4200是一个合适的设置。
尽管,pinned和classes的数值之间的差值给pCluster的初始大小提供了线索。但是,因为每一个对象可能有不同的大小,所以很难预测P簇所需要的大小和P簇溢出的大小。用户可以通过-Xp命令行参数-Xp设定P簇的初始大小和溢出大小。例如:
-Xpiiii[K][,oooo[K]]
其中,iiii代表P簇的初始大小,单位是KB,oooo是可选的,代表溢出P簇(后续的P簇)的大小。iiii和oooo的默认值为16KB和2KB。
如果用户的应用确实遇到了堆空间碎片的问题,可以考虑打开GC的详细信息并使用-Dibm.dg.trc.print=st_verify参数,并从分析值中得到合适的-Xk值。如果问题依旧存在,可以考虑试验加大P簇的初始大小和溢出大小。
对于一个大的Java应用,比如:WAS,默认的K簇可能不足以分配所有的类块。在IBM JDK1.4.2版本中,可以通过使用-Xk和-Xp命令行参数来设定K簇和P簇的大小,例如:
-Xknnnn
其中nnnn代表K簇中可以容纳的类块的最大数目。通过添加Java的运行是参数-Dibm.dg.trc.print=st_verify 可以在GC的详细信息中得到合适nnnn的值,例如:
<GC(VFY-SUM):pinned=4265(classes=3955/freeclasses=0) dosed=10388 movable=1233792free=5658>
pinned和classes的数值可以为-Xk的正确数值提供参考。一般推荐使用classes(3955)数值的110%左右,所以在这个例子中-Xk4200是一个合适的设置。
尽管,pinned和classes的数值之间的差值给pCluster的初始大小提供了线索。但是,因为每一个对象可能有不同的大小,所以很难预测P簇所需要的大小和P簇溢出的大小。用户可以通过-Xp命令行参数-Xp设定P簇的初始大小和溢出大小。例如:
-Xpiiii[K][,oooo[K]]
其中,iiii代表P簇的初始大小,单位是KB,oooo是可选的,代表溢出P簇(后续的P簇)的大小。iiii和oooo的默认值为16KB和2KB。
如果用户的应用确实遇到了堆空间碎片的问题,可以考虑打开GC的详细信息并使用-Dibm.dg.trc.print=st_verify参数,并从分析值中得到合适的-Xk值。如果问题依旧存在,可以考虑试验加大P簇的初始大小和溢出大小。
此类碎片问题无法通过重整解决。碎片只是一个通俗的说法,正确的含义是每两个p簇之前的空隙过小,可以视为碎片。由于p簇是不能移动不能删除的,所以碎片的大小完全是由类的加载情况决定的。也就是说可能某次was启动之后恰巧不会oom,也可能启动不久就会oom。
要想完全解决,只能通过实验测试出恰当的-Xp和-Xk的值
考虑的建议值:
-Xk20000 -Xp20000K, 256K
要想完全解决,只能通过实验测试出恰当的-Xp和-Xk的值
考虑的建议值:
-Xk20000 -Xp20000K, 256K
如果是SUN 虚拟机,推荐设置应该是-Xms2048M -Xmx2048M这种最大值和最小值相同的
如果是IBM虚拟机,就应该像帮助说的那样,将最小值设置的比较小,这样能够利用堆增长来最大限度的避免内存碎片。
如果是IBM虚拟机,就应该像帮助说的那样,将最小值设置的比较小,这样能够利用堆增长来最大限度的避免内存碎片。
假设我们的系统一共要生成11280个类对象(可能没这么多class,但是同一个class由不同的classloader加载的话,生成不同的类对象),那么除了k簇中存放的1280个之外,其余10000个要放到p簇中。假设初始的16k的p簇中存放的完全是线程和JNI对象,也就是说我们的类对象要用后来申请的2k一个的p簇来存放。
那么一共需要 10000*256/2048 ==1250个p簇
假设我们的堆大小为1G,那么堆内碎片的平均大小是1G/1250,也就是不到1M。
这个时候你申请1M以上的内存,就有很大的可能会遇到碎片问题造成的AF。
如果你增大了初始的K簇和后来的每个p簇的大小,无论增加哪个,都能解决这个问题。
那么一共需要 10000*256/2048 ==1250个p簇
假设我们的堆大小为1G,那么堆内碎片的平均大小是1G/1250,也就是不到1M。
这个时候你申请1M以上的内存,就有很大的可能会遇到碎片问题造成的AF。
如果你增大了初始的K簇和后来的每个p簇的大小,无论增加哪个,都能解决这个问题。
相关推荐
总结来说,面对Java IBM WebSphere的内存溢出问题,我们需要结合`javacore`和`deapdump`等诊断工具,通过分析脚本和相关库文件,理解内存管理原理,调整JVM配置,并优化代码,才能有效地排查和解决问题。
### Websphere内存溢出问题解析与解决方案 #### 一、引言 Websphere作为一款广泛应用于企业级环境的应用服务器软件,其稳定性和性能至关重要。然而,在实际使用过程中,经常会遇到内存溢出(Out Of Memory, OOM)的...
【标题】:WebSphere内存溢出 在Java应用程序服务器中,WebSphere是一个广泛使用的平台,用于部署和...通过对JVM内存参数的精细调整和对应用程序的优化,可以有效地防止和处理内存溢出问题,保证系统的高效和可靠性。
总之,对于WebSphere内存溢出问题,Javacore分析工具JCA 456是开发者的重要助手,它能帮助我们快速定位问题,有效地解决问题,保证系统的稳定运行。正确理解和使用这类工具,对于提升企业应用的性能和可靠性至关重要...
总之,ha456.jar是一个强大的Websphere内存溢出诊断工具,能够帮助开发者定位和解决内存管理问题,提升应用的稳定性和性能。通过深入理解和有效利用这样的工具,可以在面对复杂的企业级应用环境时,更好地管理和优化...
标题中的“was内存溢出 javacore分析工具jca 401”指的是在WebSphere应用服务器(WAS)环境中,出现内存溢出问题时,使用名为JCA(Java Core Analysis)401的工具进行分析的情况。内存溢出是程序运行过程中,因分配...
### Weblogic内存溢出优化设置详解 #### 一、解决中文显示问题 在Weblogic环境中,如果遇到中文显示异常的情况,通常是因为操作系统本身不支持中文字符集。为了解决这个问题,可以通过修改`startweblogic.sh`...
该文档整合了网上所有的关于描述was(webSphere)下生成许多phd文件的...产生该类文件的原因包括JVM设置的最小内存太小,以至于内存溢出,还有就是程序漏洞,使得JVM内存溢出,文档中叶介绍了websphere的检测工具的使用
2. **使用Tivoli Performance Viewer检测内存溢出状况** 3. **获取详细的垃圾收集(GC)日志** 4. **获取Java堆内存快照(Heap Dump)** 5. **解读详细的垃圾收集日志** 6. **分析Java堆内存快照** #### 四、什么是...
内存溢出(Out Of Memory,简称OOM)是计算机科学中的一种常见问题,特别是在软件开发和系统管理领域。当一个程序在运行过程中请求的内存超过了操作系统或应用程序能够分配的最大内存时,就会发生内存溢出。这个问题...
软件介绍: IBM websphere 服务器出现内存溢出或其他故障时,会生成heapdump文件,本工具用于分析heapdump,查找错误原因。运行IBN WEBSPHERE HEAPDUMP需要安装JDK1.8框架。
这款工具集可以帮助开发者和管理员深入理解Websphere运行时环境,识别并解决各种性能问题,包括内存溢出、线程死锁以及垃圾回收问题。在本文中,我们将详细探讨这些关键问题及其解决方案。 首先,内存溢出是Java...
IBM内存查看工具是一款专为解决IBM WebSphere Application Server (WAS) 内存溢出问题而设计的应用程序。它能够帮助管理员深入理解WAS的内存使用情况,有效地分析内存升降关系,以及对日志文件和内存溢出文件进行...
- **IBM_HEAPDUMP_OUTOFMEMORY**: 当遇到内存溢出时,自动触发堆转储,设置为`true`。 - **IBM_JAVADUMP_OUTOFMEMORY**: 遇到内存溢出时,自动生成Java核心文件,设置为`true`。 - **IBM_JAVA_HEAPDUMP_TEXT**: 生成...
- **非堆内存**:包括元空间、代码缓存等,查看其占用情况以避免溢出问题。 - **垃圾回收**:监控GC频率和耗时,过高可能影响应用响应速度。 2. **CPU使用率** 监控WebSphere进程的CPU使用率,过高可能表示存在...
JAVA 内存分析指引201007_V0.2文档主要涵盖了Java内存管理和分析的关键概念,旨在解决生产环境中常见的内存溢出问题。本文档适用于基于WebSphere 5和6的应用部署,尤其是在Windows和AIX操作系统上的环境。 1. **...
#### 核心知识点:WebSphere性能调优之内存溢出问题 在IT运维与开发领域,WebSphere作为一款广泛应用于企业级环境的应用服务器,其性能调优一直是确保系统稳定运行的关键。本文将深入探讨WebSphere在运行过程中遇到...
当WebSphere遇到性能问题,如内存溢出,我们通常需要进行深入的诊断。"heapdump"是一种重要的诊断手段,它能记录下JVM(Java虚拟机)在某一时刻的内存状态。本篇文章将详细介绍如何利用IBM WebSphere生成heapdump...
诊断内存溢出问题的步骤包括: 1. **检查JVM参数配置**:确认JVM内存参数是否设置合理,尤其是在高负载场景下。 2. **检查系统日志**:分析`SystemOut.log`等日志文件,寻找异常信息。 3. **收集内存溢出信息**:...