您的位置: 汕尾资讯网 > 科技

Java EE 常见性能问题解决手册7

发布时间:2019-09-13 19:46:23

图4展示了一个小幅度调整是如何运行的

图4:当垃圾收集器释放所有的无效的对象并把有效的对象移动到一个更紧凑整齐的新空间,它将EDEN和生存者空间清空。

以上就是SUN实现的垃圾收集器机制,你可以看出在老一代中的对象会被大幅度调整器收集清除。长生命周期的对象的清除花费的代价很高,因此如果你希望生命周期短的对象在占据空间前及时的死亡,就需要一个主垃圾收集器去回收他们的内存。

上面所讲解的东西是为了更好的帮助我们识别出内存泄漏。当JAVA中的一个对象包含了一个并不想要的一个指向其他对象的引用的时候,内存就会泄漏,这个引用阻止了垃圾收集器去回收它所占据的内存。采用这种机制的SUN 虚拟机,对象不会被丢弃,而是利用自己特有的方法把他们从乐园和幸存者空间移动到老一代地区。因此,在一个基于多用户的WEB环境,如果许多请求造成了泄漏,你就会发现老一代的增长。

图5显示了那些潜在可能造成泄漏的对象:主收集器收集后遗留下来占据空间的对象会越来越多。不是所有的占据空间的对象都造成内存泄漏,但是造成内存泄漏的对象最终都占据者空间。如果内存泄漏的确存在,这些造成泄漏的对象就会不断的占据空间,直至造成内存溢出。

因此,我们需要去跟踪垃圾收集器在处理老一代中的运行:每次垃圾收集器大幅度收集运行时,有多少内存被释放?老一代内容是不是按一定的原理来增长?

图5。阴影表示在经过大幅度的收集后幸存下来的对象,这些对象是潜在可能引发内存泄漏的对象

一部分这些相关的信息是可以通过跟踪API得到,更详细的信息通过详细的垃圾收集器的日志也可以看到。和所有的跟踪技术一样,日值记录详细的程度影响着JVM的性能,你想得到的信息越详细,付出的代价也就越高。为了能够判断内存是否泄漏,我使用了能够显示辈分之间所有的不同的较权威的技术来显示他们的区别,并以此来得到结果。SUN 的日志报告提供的信息比这个详细的程度超过5%,我的很多客户都一直使用那些设置来保证他们管理和调整垃圾收集器。下面的这个设置能够给你提供足够的分析数据:

–verbose:gc –xloggc:gc.log –XX:+PrintGCDetails –XX:+PrintGCTimeStamps

明确发现在整个堆中存在有潜在可能泄漏内存的情况,用老一代增长的速率才比较有说服力。切记调查不能决定些什么:为了能够最终确定你内存泄漏,你需要离线在内存模拟器中运行你的应用程序。

IBM JVM内存管理模式

IBM的JVM的机制有一点不同。它不是运行在一个巨大的继承HEAP中,它仅在一个单一的地区维护了所有的对象同时随着堆的增长来释放内存。这个堆是这样运行的:在一开始运行的时候,它会很小,随着对象实例不断的填充,在需要执行垃圾收集的地方清除掉无效的对象同时把所有有效的对象紧凑的放置到堆的底部。因此你可能猜测到了,如果想寻找可能发生的内存泄漏应该观察堆中所有的动作,堆的使用率是在提高?

如何分析内存泄漏

内存泄漏非常难确定,如果你能够确定是请求导致的,那你的工作就非常简单了。把你的程序放入到运行环境中,并在内存模拟器中运行,按下面的步骤来:

1. 在内存模拟器中运行你的应用程序   2. 执行使用方案(制造请求)以便让程序在内存中装载请求所需要的所有的对象,这可以为以后详细的分析排除不必要的干扰   3. 在执行使用方案前对堆进行拍照以便捕获其中所有运行的对象。   4. 再次运行使用方案。   5. 再次拍照,来捕获使用方案运行之后堆中所有对象的状态。   6. 比较这2个快照,找出执行使用方案后本不应该出现在堆中的对象。  这个时候,你需要去和开发者交流,告诉他你所碰到的棘手的请求,他们可以判断究竟是对象泄漏还是为了某个目的特地让对象保留下来的。如果执行完后并没有发现内存泄漏的情况,我一般会转到步骤4再进行多次类似的跟踪。比如,我可能会将我的请求反复运行17次,希望我的泄漏分析能够得到17个情况(或更多)。这个方法不一定总有用,但如果是因为请求引起的对象泄漏的话,就会有很大的帮助。

如果你无法明确的判断泄漏是因为请求引发的,你有2个选择:

1. 模拟每一个被怀疑的请求直至发现内存泄漏   2. 存配置一个内存性能跟踪工具  第一个选项在小应用程序中是确实可用的或者你非常走运的解决了问题,但对大型应用程序不太有用。如果你有跟踪工具的话第二个选择是比较有用的。这些工具利用字节流工具跟踪对象的创建和销毁的数量,他们可以报告特定类中的对象的数量状态,例如把Collections类作为特定的请求。例如,一个跟踪工具可以跟踪/action/login.do请求,并在它完成后将其中的100个对象放入HASHMAP中。这个报告并不能告诉你造成泄漏的是代码还是某个对象,而是告诉你在内存模拟器中应该留意那些类型的请求。把程序服务器放到产品环境中并不会使他们变敏感,而是跟踪性能的工具可以使你的工作变的更简单化。

虚假内存泄漏

少数的一些问题看起来是内存泄漏实际上并非如此。

我将这些情况称为假泄漏,表现在下面几种情况:

1. 分析过早   2. Session泄漏   3. 异常的持久区域  这章节对这些假泄漏都进行了调查,描述了如何去判断这些情况以及如何处理.

不要过早分析

为了在寻找内存泄漏的时候尽量减少出现判断错误的可能性,你应当在适当的时候分析堆。危险是:一些生命周期长的对象需要装载到堆中,因此在堆达到稳定状态且包含了核心对象之前具有很大的欺骗性。在分析堆之前,应该让应用程序达到稳定状态。

为了判断是否过早的对堆进行分析,持续2个小时对跟踪到的分析快照进行分析,看堆的使用率是上升还是下降。如果是下降,保存这个时候的内存记录。如果是上升,这个时候就需要分析内存中的SESSION了。

糖尿病胃轻瘫消化不好的原因
小儿呕吐吐奶溢乳哭闹怎么办
男性突然夜尿增多怎么办
如何消除小儿积食
猜你会喜欢的
猜你会喜欢的