用户在使用WebSphere Application Server(以下简称WAS)运行自己应用的时候经常会碰到Out Of Memory的问题(简称OOM问题),其中很大一部分的情况是Java堆空间碎片问题引起的OOM问题。IBM JDK 1.4.2的版本中JDK对GC的行为做出了一定的改进。其中一些JDK参数的引进可以改善Java堆空间的碎片问题。
本文首先会给出IBM JDK 1.4.2中对于K簇(k-cluster)和P簇(p-cluster)工作模式的解释。然后在此基础上介绍JDK 1.4.2为解决碎片问题采取的新算法。最后,给出WAS中为改善Java堆空间碎片问题使用的JDK运行参数。
一、K簇和P簇
在Java堆空间中分配的内存对象通常是可以移动,如果垃圾回收程序(garbage collector)决定重新序列化堆空间的时候,可以四处移动这些对象。然而,有些对象永远或者临时无法移动。这些固定不动的对象就是常说的pin对象(pinned object)。
在IBM JDK 1.4.2中,垃圾回收程序首先会分配一个K簇作为堆空间底部的第一个对象。K簇是专门用来存储“类块”(class block)的区域。K簇可以容纳1280个类块条目。每个类块的大小是256个字节。紧接着垃圾回收程序会分配一个P簇作为堆空间中的第2个对象。P簇是用来存储pin对象的区域。第一个P簇的默认大小为16KB。
当K簇满了的情况下,垃圾回收程序在P簇中继续分配类块。当P簇满了的情况下,垃圾回收程序会分配一个大小为2KB的新P簇。由于这些新的P簇可以被分配到任何地方而且又不能被移动,这就造成了碎片的问题。
二、pinnedFreeList算法
为了解决这些问题,IBM JDK 1.4.2版本中起用了pinnedFreeList来改变P簇的分配方法。方法的关键是在每一次GC(garbage collection)后,垃圾回收程序从未分配列表的底部分配一些存储区并把它们串到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 JDK 1.4.2版本中,可以通过使用-Xk和-Xp命令行参数来设定K簇和P簇的大小,例如:-Xknnnn (其中nnnn代表K簇中可以容纳的类块的最大数目。)
通过添加Java的运行是参数-Dibm.dg.trc.print=st_verify 可以在GC的详细信息中得到合适nnnn的值,例如:
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簇的初始大小和溢出大小。
出处:http://www-900.ibm.com/cn/support/viewdoc/detail?DocId=2447476A10000
分享到:
相关推荐
下面将详细介绍JDK 1.4.2中的核心知识点和它在Java历史上的作用。 1. **NIO (New I/O) 模块**:Java 1.4 引入了NIO(非阻塞I/O)框架,这是对传统I/O模型的重大改进。NIO提供了更高效的数据传输方式,特别是在处理...
jdk1.4老资源,留一份自用。JDK1.4.2 无需安装,解压后直接使用。
由于 JDK 1.4.2 已经非常过时,不支持现代的 Java 特性,如模块系统(Project Jigsaw)、Lambda 表达式等,也不包含安全补丁和性能优化,因此除非有特定需求,否则不建议在生产环境中使用。对于学习和研究目的,理解...
JDK 1.4.2 是Java历史上的一个重要版本,发布于2004年,它引入了许多新的特性和改进,对当时的Java开发者具有重大意义。本篇将深入探讨JDK 1.4.2的官方英文API中的关键知识点。 1. **NIO (Non-blocking I/O)** JDK...
在JDK1.4.2中,`launcher`主要实现了命令行参数解析、JVM选择与启动、类路径设置等功能。通过研究这部分源代码,可以了解Java程序如何启动及环境变量如何影响程序运行。 2. `java`、`javax`、`com`、`org`、`sunw`...
总的来说,JDK1.4.2_08是Java发展历程中的一个重要里程碑,它的各种改进和新特性为Java开发者提供了更强大、更稳定的开发环境。虽然现在最新的JDK版本已经更新到了许多个版本,但理解并掌握早期版本的功能和特性对于...
这个描述表明`jdk1.4.2_06`是一个早期版本的Java Development Kit(JDK),在当前的互联网资源中已经相对稀少。JDK是Oracle公司提供的用于开发和运行Java应用程序的工具集合,它包含了Java编译器、调试器、JVM(Java...
在标题"非安装jdk1.4.2.rar"中,关键词“非安装版”指的是这个JDK版本不需要通过传统意义上的安装过程。通常,安装版的软件会将所有必要的文件和配置信息写入系统注册表或其他特定位置,而“非安装版”或“便携版”...
2. **正则表达式**: Java 1.4.2 加入了对正则表达式的全面支持,通过`java.util.regex`包提供,这使得在Java中进行文本模式匹配和处理变得更加方便。 3. **异常链**: 在这个版本中,异常可以携带一个"链",即一个...
JDK1.4.2中文帮助文档.CHM
JDK1.4.2是Java发展历程中的一个重要里程碑,其中引入了一些关键特性: 1. **NIO(New Input/Output)**:提供了一种非阻塞I/O模型,允许程序在处理多个输入/输出流时提高效率,特别适用于网络和大文件操作。 2. *...
在实际开发中,JDK 1.4.2的API提供了大量的类和接口,如`java.awt`和`javax.swing`用于图形用户界面设计,`java.net`处理网络通信,`java.sql`支持数据库连接。这些丰富的API使得开发者可以构建出功能强大的应用程序...
对于那些需要向后兼容或在特定环境中运行旧版Java应用的用户来说,JDK 1.4.2_04仍然是一个可靠的选择。然而,由于技术的不断进步和新安全问题的出现,现在推荐使用更新的JDK版本,如JDK 8或更高版本,它们提供了更多...
虽然现在jdk1.6都很成熟了。但是如果需要修改系统,jdk1.4当然是很多开发人员的首选
JDK1.4.2的CHM版手册 这个很棒哦,比起sun的docs要方便的多,而且内容一点不差, 需要的就下吧, 晕了,上传居然不能大于5m
例如,如果你需要测试应用程序在Java 1.4环境下的行为,或者分析旧代码如何与新版本的Java交互,这个版本的JDK就派上用场了。 **注意事项:** 由于JDK 1.4.2_07的年代久远,它可能不支持现代的Java特性,也不再...
JDK1.4.2的CHM版手册 这个很棒哦,比起sun的docs要方便的多,而且内容一点不差, 需要的就下吧, 晕了,上传居然不能大于5m 总共有九个分卷
Java Runtime Environment (JRE) 1.4.2 是Java应用程序执行所需的关键组件,它为开发者和用户提供了在各种操作系统上运行Java应用的基础。这个版本是Sun Microsystems在2004年发布的一个重要里程碑,它在Java技术的...
在使用IBM JDK 1.6进行开发时,开发者需要注意兼容性问题,因为随着时间的推移,新的Java版本可能会弃用旧的功能。同时,虽然IBM JDK提供了性能优势,但在某些特定场景下,可能需要与Oracle JDK进行对比测试,以确定...
JDK1.4.2 编程工具 java 编程。。。。。。。。。。。。。。。。。