科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道使用技巧:Java EE性能问题解决手册5

使用技巧:Java EE性能问题解决手册5

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

这篇文章,是PRO JAVA EE 5 Performance Management and Optimization 的一个章节,作者Steven Haines分享了他在调优企业级JAVA应用时所遇到的常见问题。

来源:IT专家网 2008年6月4日

关键字: 手册 3977 Java EE java

  • 评论
  • 分享微博
  • 分享邮件
异常的持久空间

  容易误解JVM为持久空间分配内存的目的。堆仅仅存储类的实例,但JVM在堆中创建类实例之前,它必须把字节流文件(.class文件)装载到程序内存中。它利用内存中的字节流在堆中创建类的实例。JVM利用程序的内存来装载字节流文件,这个内存空间称为持久空间。图6显示了持久空间和堆的关系:它存在于JVM程序中,并不是堆的一部分。

  Figure 6. The relationship between the permanent space and the heap

  通常,你可能想让你的持久空间足够大以便于它能够装载你程序所有的类,因为很明显,从文件系统中读取类文件比从内存中装载代价高很多。JVM提供了一个参数让你不的程序不卸载已经装载到持久空间中的类文件:

  –noclassgc

这个参数选项告诉JVM不要跑到持久空间去执行垃圾收集释放其中已经装载的类文件。这个参数选项很聪明,但是会引起一个问题:当持久空间满了以后依然需要装载新文件的时候JVM会怎么处理呢?我观测到的资料说明:如果JVM检测到持久空间还需要内存,就会调用主垃圾收集程序。垃圾收集器清除堆,但它并不会对持久空间进行任何操作,因此它的努力是白费的。于是JVM就再重新检测持久空间,看它是否满,然后再次执行程序,一遍的一遍重复。

  我第一次碰到这种问题的时候,用户抱怨说程序性能很差劲,并且在运行了几次后就出现了问题,可能是内存溢出问题。在我调查了详细的关于堆和程序内存利用的收集器的记录后,我迅速发觉堆的状态非常正常,但程序确发生了内存溢出。这个用户维持了数千的JSP页面,在装载到内存前把他们都编译成了字节流文件放入持久空间。他的环境已经造成了持久空间溢出,但是在堆中由于用了 -noclassgc 选项,于是JVM并不去释放类文件来装载新的类文件。于是就导致了内存溢出错误,我把他的持久空间改为512M大小,并去掉了 -noclassgc 参数。

  正像图7显示的,当持久空间变满了的时候,就引发垃圾收集,清理了乐园和幸存者空间,但是并不释放持久空间中的一点内存。

  Figure 7. Garbage collection behavior when the permanent space becomes full. Click on thumbnail to view full-sized image.

  注意

  当设置持久空间大小时候,一般考虑128M,除非你的程序有很多的类文件,这个时候,你就可以考虑使用256M大小。如果你想让他能够装载所有的类的时候,就会导致一个典型的结构错误。设置成512M就足够了,它仅仅是暂时的时间的花费。把持久空间设置成512M大小就象给一个脚痛的人吃止痛药,虽然暂时缓解了痛,但是脚还是没有好,依然需要医生把痛治疗好,否则只是把问题延迟了而已。

  线程池

  外界同WEB或程序服务器连接的主要方法就是向他们发送请求,这些请求被放置到程序的执行次序队列中。和内存最大的冲突就是程序服务器所设置的线程池的大小。线程池的大小就是程序可以同时处理的请求的数量。如果池太小,请求就需要在队列中等待程序处理,如果太大,CPU就需要花费太多的时间在这些众多的线程之间来回的切换。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章