最近碰到一个棘手的问题,在已经展开的稳定性测试中。频繁出现Was宕机等问题,于是在征询了研发组意见后。决定对Was发生宕机前后,进行内存快照。最初的方案是在,Was启动后和发生死机时,使用HeapDump来分析具体程序调用的Java对象。但时间的快照文件却非常难以分析发生宕机时候内存堆内具体的变化情况。由于,需要准确定位到java虚拟机中堆栈的使用情况。由此,我们引用了一个新的测试分析工具jProbe对Was启动时,场景运行的开始点、Action1的结束点以及场景运行的结束点进行内存分析。jProbe的核心思想是通过对比多次快照的内存调用情况,分析出前后两次不同的内存启动后占用比率,从而引导研发推断出程序可能发生问题的对象。
Java程序中也有内存漏洞?当然有。与流行的观念相反,在Java编程中,内存管理仍然是需要考虑的问题。在本文中,您将了解到什么会导致内存漏洞以及何时应该关注这些漏洞。您还有机会实践一下在您自己的项目中解决漏洞问题。
Java程序中的内存漏洞是如何显现出来的
大多数程序员都知道,使用像Java这样的编程语言的一大好处就是,他们不必再担心内存的分配和释放问题。您只须创建对象,当应用程序不再需要这些对象时,Java会通过一种称为“垃圾收集”的机制将这些对象删除。这种处理意味着Java已经解决了困扰其他编程语言的烦人问题 -- 可怕的内存漏洞。是这样的吗?
在深入讨论之前,我们先回顾一下垃圾收集的工作方式。垃圾收集器的工作是发现应用程序不再需要的对象,并在这些对象不再被访问或引用时将它们删除。垃圾收集器从根节点(在Java应用程序的整个生存周期内始终存在的那些类)开始,遍历被引用的所有节点进行清除。在它遍历这些节点的同时,它跟踪哪些对象当前正被引用着。任何类只要不再被引用,它就符合垃圾收集的条件。当删除这些对象以后,就可将它们所占用的内存资源返回给Java虚拟机 (JVM)。
所以的确是这样,Java代码不要求程序员负责内存的管理和清除,它会自动对无用的对象执行垃圾收集。但是,要紧记的一点是仅当一个对象不再被引用时才会被统计为无用的。图1说明了这个概念。
![]() |
| 图 1. 无用但仍被引用的对象 |
上面说明了在Java应用程序执行期间具有不同生存周期的两个类。类A首先被实例化,并会在很长一段时间或程序的整个生存期内存在。在某个时候,类B被创建,类A添加对这个新创建的类的一个引用。现在,我们假定类B是某个用户界面小部件,它由用户显示甚至解除。如果没有清除类A对B的引用,则即便不再需要类B,并且即便在执行下一个垃圾收集周期以后,类B仍将存在并占用内存空间。
何时应该关注内存漏洞?
如果您的程序在执行一段时间以后发出java.lang.OutOfMemoryError错误,则内存漏洞肯定是一个重大嫌疑。除了这种明显的情况之外,何时还应该关注内存漏洞呢?持完美主义观点的程序员肯定会回答,应该查找并纠正所有内存漏洞。但是,在得出这个结论之前,还有几个方面需要考虑,包括程序的生存期和漏洞的大小。
完全有这样的可能,垃圾收集器在应用程序的生存期内可能始终不会运行。不能保证JVM何时以及是否会调用垃圾收集器 -- 即便程序显式地调用System.gc()也是如此。通常,在当前的可用内存能够满足程序的内存需求时,JVM 不会自动运行垃圾收集器。当可用内存不能满足需求时,JVM将首先尝试通过调用垃圾收集来释放出更多的可用内存。如果这种尝试仍然不能释放足够的资源,JVM 将从操作系统获取更多的内存,直至达到允许的最大极限。
例如,考虑一个小型Java应用程序,它显示一些用于修改配置的简单用户界面元素,并且它有一个内存漏洞。很可能到应用程序关闭时也不会调用垃圾收集器,因为JVM很可能有足够的内存来创建程序所需的全部对象,而此后可用内存则所剩无几。因此,在这种情况下,即使某些“死”对象在程序执行时占用着内存,它实际上并没有什么用途。
如果正在开发的Java代码要全天24小时在服务器上运行,则内存漏洞在此处的影响就比在我们的配置实用程序中的影响要大得多。在要长时间运行的某些代码中,即使最小的漏洞也会导致JVM耗尽全部可用内存。
在相反的情况下,即便程序的生存期较短,如果存在分配大量临时对象(或者若干吞噬大量内存的对象)的任何Java代码,而且当不再需要这些对象时也没有取消对它们的引用,则仍然可能达到内存极限。
最后一种情况是内存漏洞无关紧要。我们不应该认为Java内存漏洞像其他语言(如 C++)中的漏洞那样危险,在那些语言中内存将丢失,且永远不会被返回给操作系统。在Java应用程序中,我们使不需要的对象依附于操作系统为JVM 所提供的内存资源。所以从理论上讲,一旦关闭Java应用程序及其JVM,所分配的全部内存将被返回给操作系统。
| 共2页: 1 [2] 下一页 | ||
|
|
||||
| · 网络故障排除宝典 · 访问控制列表(ACL)介绍 · 视频访谈:网管员如何踏.. · 首届中国IT工程师生态.. · 华为路由器配置 · 全面解析35岁技术人的.. · 企业数据恢复指南 · 龙芯要做中国的“奔腾” |
· 2008年上半年全国软考.. · 交换机故障解决指南 · Vista SP1对决XP SP3 · LAMP技术精解 · 微软出价446亿美元收购.. · AIX操作系统管理应用(.. · 华为员工自杀频频拷问.. · 三层交换技术专题 |
|||
|
||||
| · SQL Server 2008/2005.. · SOA 面向服务架构 · SQL Server 2008/2005.. · iSCSI应用与发展 · RAID——磁盘阵列基础 · Apache技术专题 · 三层交换技术专题 · SQL Server入门到精通 |
· Apache技术专题 · 国际文档格式标准开战 · 路由器设置与口令恢复 · 打造安全服务器 · PHP开发应用手册 · SOA 面向服务架构 · 企业数据恢复指南 · ADSL应用面面俱到 |
|||
|
||||
| · iSCSI应用与发展 · SQL Server入门到精通 · SQL Server 2008/2005.. · SOA 面向服务架构 · Apache技术专题 · iSCSI应用与发展 · 三层交换技术专题 · Apache技术专题 |
· 企业数据恢复指南 · RAID——磁盘阵列基础 · 路由器设置与口令恢复 · SOA 面向服务架构 · ADSL应用面面俱到 · ADSL应用面面俱到 · 反垃圾邮件技术应用 · 访问控制列表(ACL)介绍 |
|||