我即将使用JProfiler和Eclipse Tptp.对java应用程序进行研讨会分析,性能调整,内存分析,内存泄漏检测等 我需要一套练习,我可以为参与者提供: 使用该工具来分析发现问题:瓶颈,内存泄漏,次优代码等。我相信有丰富的经验和现实生活中的例子。
问题和解决方案不应过于复杂;应该可以在几分钟内解决它们,最坏的情况是几小时。 一些有趣的领域:
理想情况下,练习应包括未经优化的样本代码和解决方案代码。
答案 0 :(得分:6)
我试图找到我在野外看到的现实生活中的例子(可能稍有改动,但基本问题都非常真实)。我也尝试将它们聚集在同一场景中,这样你就可以轻松地建立一个会话。
场景:您有一个耗时的功能,您希望对不同的值执行多次,但可能会再次弹出相同的值(理想情况下,创建后不会太长)。一个好的和简单的例子是你需要下载和处理的url-web页面对(对于练习它应该可能被模拟)。
循环:
您想要检查页面中是否弹出任何一组单词。在循环中使用您的函数,但使用相同的值,伪代码:
for (word : words) {
checkWord(download(url))
}
一个解决方案非常简单,只需在循环之前下载页面即可。 其他解决方案如下。
内存泄漏:
WeakHashMap
实现以前的缓存,其中键是URL(不是字符串,请参阅后面的内容),值是包含URL的类的实例,下载的页面和别的。您可能认为它应该没问题,但实际上它不是:因为值(没有被弱引用)具有对密钥(URL)的引用,密钥永远不会有资格清理 - >好记忆泄漏。对象创建&字符串:
并发性:
您希望通过并行下载/过滤来加速整个过程。创建一些线程并使用它们运行代码,但是在一个大的同步块(基于缓存)中执行所有操作,只是“保护缓存免受并发问题”。效果应该是你有效地只使用一个线程,因为所有其他线程都在等待获取缓存上的锁 解决方案:仅围绕缓存操作进行同步(例如,使用`java.util.collections.synchronizedMap())
同步所有微小的代码片段。这应该会破坏性能,可能会阻止正常的并行执行。如果你足够幸运/聪明,你也可以拿出死锁。 这样做的道德:同步不应该是一个临时的事情,在“它不会伤害”的基础上,而是一个深思熟虑的事情。
奖金练习:
在开始时填写缓存,之后不要进行太多分配,但仍然会在某处发生小泄漏。通常这种模式不容易捕捉。您可以使用分析器的“书签”或“水印”功能,该功能应在缓存完成后立即创建。
答案 1 :(得分:1)
不要忽略this method,因为它适用于these reasons的任何语言和操作系统。一个例子是here。此外,尝试使用具有I / O和显着调用深度的示例。不要只使用像Mandelbrot这样的小型cpu绑定程序。如果你拿那个不太大的C例子,并用Java重新编码,这应该说明你的大部分要点。
让我们看看:
解决内存泄漏问题 垃圾收集器的重点是插入内存泄漏。但是,您仍然可以分配太多内存,并且在某些对象的“新”中显示为很大一部分时间。
优化循环。
一般来说,循环不需要优化,除非它们内部完成的很少(并且它们需要很长的时间)。
优化对象创建和管理 这里的基本方法是:保持数据结构尽可能简单。特别是远离通知式尝试以保持数据一致,因为这些事情会消失并使调用树变得非常浓密。这是大软件性能问题的主要原因。
优化字符串操作 使用字符串构建器,但不要使用不会占用大量执行时间的代码。
并发。
并发有两个目的
1)性能,但此仅的工作范围允许多个硬件同时启动。如果没有硬件,则无济于事。这很疼。
2)表达的清晰度,例如UI代码不必担心同时进行大量计算或网络I / O.
在任何情况下,它都不能被强调,在你证明某些东西需要很长时间之前不做任何优化。
答案 2 :(得分:0)
我已经使用JProfiler来分析我们的应用程序。但它没有多大帮助。然后我使用JHat.Using JHat你无法实时看到堆。你必须进行堆转储然后分析它。使用OQL(Object Query Language)是查找堆泄漏的好方法。