如何将 JProfiler 限制为子树
Posted
技术标签:
【中文标题】如何将 JProfiler 限制为子树【英文标题】:How to limit JProfiler to a subtree 【发布时间】:2015-06-29 17:33:43 【问题描述】:我有一个名为 com.acmesoftware.shared.AbstractDerivedBean.getDerivedUniqueId() 的方法。当我使用 JProfiler 应用程序时,这个方法 getDerivedUniqueId() 基本上像预期的那样被深埋了 80 个方法。代表应用程序中的每个 bean 调用该方法。我试图从这个方法开始记录 CPU 调用树到叶节点(即,排除的类之一)。
我尝试了以下方法,但没有产生预期的结果:
-
在分析目标方法之上找到一个方法,例如 markForDeletion()。
设置触发器以在 getDerivedUniqueId() 处开始录制
将触发器设置为在 markForDeletion() 处停止录制
我原以为只能看到 markForDeletion() 以下的所有内容,但我看到了所有内容,但没有包括 getDerivedUniqueId(),这与我的预期目标相反。更糟糕的是,即使使用 5ms 采样,此触发器也会将之前的运行时间从 10 分钟增加到“我在运行 3 小时后终止”。似乎触发器是在开销之上增加了大量的开销。因此,即使我知道如何正确启用触发器,增加的开销似乎也会使其无效。
我需要将记录限制为仅此方法的原因是:在 5ms 采样模式下运行时,应用程序在 10 分钟内完成。当我在完整的仪器中运行它时,我已经等了 3 个小时,它仍然没有完成。因此,我只需要在调用 getDerivedUniqueId() 后打开完整检测,并在退出 getDerivedUniqueId() 时暂停分析。
-- 更新/编辑: 感谢英戈·凯格尔的帮助。 我可能不清楚如何使用触发器。在下面的代码中,我设置了触发器,如代码后所示。我的期望是,当我使用以下配置的触发器对应用程序(采样和完整检测)进行 JProfile 时,如果 boolean isCollectMetrics 为 false,我应该在过滤的类中看到 100% 或 99.9% 的 cpu。然而,事实并非如此。 CPU 树似乎没有考虑触发器。 其次,当 isCollectMetrics 为 true 时,我期望的 jprofiler 调用树将以 startProfiling() 开始并以 stopProfiling() 结束。同样,情况也并非如此。
方法 contains() 是瓶颈。它最终调用 150 个 getDerivedUniqueId() 之一。我试图查明哪个 getDerivedUniqueId() 导致性能下降。
public static final AtomicLong doEqualContentTime = new AtomicLong();
public static final AtomicLong instCount = new AtomicLong();
protected boolean contentsEqual(final InstanceSetValue that)
if (isCollectMetrics)
// initialization code removed for clarity
// ..........
// ..........
final Set<Instance> c1 = getReferences();
final Set<Instance> c2 = that.getReferences();
long st = startProfiling(); /// <------- start here
for (final Instance inst : c1)
instCount.incrementAndGet();
if (!c2.contains(inst))
long et = stopProfiling(); /// <------- stop here
doEqualContentTime.addAndGet(et - st);
return false;
long et = stopProfiling(); /// <------- stop here
doEqualContentTime.addAndGet(et - st);
return true;
else
// same code path as above but w/o the profiling. code removed for bravity.
// ......
// ......
return true;
public long startProfiling()
return System.nanoTime();
public long stopProfiling()
return System.nanoTime();
public static void reset()
doEqualContentTime.set(0);
instCount.set(0);
启用的触发器:
startProfiling 触发器:
stopProfiling 触发器:
我已分别尝试使用“开始录制”或“录制 CPU”按钮来仅捕获调用树
【问题讨论】:
【参考方案1】:如果检测的开销很大,您应该优化您的过滤器。使用好的过滤器,检测开销可以非常小,
关于触发器设置,正确的操作是:
-
“开始录制”并选择 CPU 数据
“等待事件完成”
“停止录制”并选择 CPU 数据
【讨论】:
嗨。我不清楚你的建议。上述步骤与您的建议不相似。您能否提供详细步骤以将检测范围缩小到仅以 getDerivedUniqueId() 开头的调用树,并在合理的时间内完成任务。谢谢。 那么您的触发器中是否有我建议的确切操作?我在你的屏幕截图中没有看到。我确实提供了您想要做的详细步骤。如果不详细了解您的应用程序,我就无法改进您的过滤器。 嗨英戈。感谢您的帮助。我已更新问题以包含代码和 JProfiler 快照。我不能包括调用树,因为它是公司专有的。我可以通过电子邮件/Skype 向您发送 jprofiler 调用树屏幕截图吗?谢谢。 不,我提到的所有三个操作都必须在您的测量根的同一方法触发器中,而不是在单独的触发器中。 如果 stopProfiling() 和 startProfiling() 方法都在同一个触发器中,并且操作页面同时包含启动和停止,则无法将 stopProfiling() 与停止操作相关联,同样对于开始分析。您是否暗示创建触发器时指定方法页面中的方法顺序与操作页面中的操作顺序相关?以上是关于如何将 JProfiler 限制为子树的主要内容,如果未能解决你的问题,请参考以下文章
如何在 JProfiler 离线模式下使用触发器进行分析时自动获取保留的内存
如何使用 jprofiler 分析 gwt 客户端应用程序?