在Java中,在对象创建时保存堆栈跟踪,并在程序的任何其他位置使用它。

huangapple go评论72阅读模式
英文:

Saving stack trace in java for any object at the time of it's creation and using it at any other point in the program

问题

为了调试目的,我希望在创建对象时保存堆栈跟踪,并在程序的后续阶段引用/打印它。我尝试过在OpenJDK的Object类中添加一个字段,但正如这里所提到的,这将会导致OpenJDK中的硬编码元素出现问题。

有人能否提供一种高效的方法来实现这一点。

英文:

For debugging purpose, I want to save the stack trace when an object was created and refer/print it at a later point in the program. I tried adding a field to Object class in OpenJDK itself but as mentioned in here it will cause a problem with hard coded elements in OpenJDK.

Can someone please suggest an efficient way to do this.

答案1

得分: 2

如果对象较大或频繁,JFR将对分配进行采样。默认情况下,它每秒采样多达150次。

JDK 16或更新版本:

$ java -XX:StartFlightRecording:filename=exitdump.jfr MyApp
...
停止应用程序
$ jfr print --events ObjectAllocationSample --stack-depth 64 exitdump.jfr

jdk.ObjectAllocationSample {
  startTime = 12:00:19.826
  objectClass = byte[](classLoader = bootstrap)
  weight = 23.1 kB
  eventThread = "Image Animator 0"(javaThreadId = 33)
  stackTrace = [
    sun.awt.image.GifFrame.dispose() line: 723
    sun.awt.image.GifImageDecoder.produceImage() line: 247
    sun.awt.image.InputStreamImageSource.doFetch() line: 269
    sun.awt.image.ImageFetcher.fetchloop() line: 212
    sun.awt.image.ImageFetcher.run() line: 176
  ]
}
...
英文:

If the object is large, or frequent, JFR will sample the allocation. By default it samples up to 150 times/s.

JDK 16, or later:

$ java -XX:StartFlightRecording:filename=exitdump.jfr MyApp
...
Stop the application
$ jfr print --events ObjectAllocationSample --stack-depth 64 exitdump.jfr

jdk.ObjectAllocationSample {
  startTime = 12:00:19.826
  objectClass = byte[] (classLoader = bootstrap)
  weight = 23.1 kB
  eventThread = "Image Animator 0" (javaThreadId = 33)
  stackTrace = [
    sun.awt.image.GifFrame.dispose() line: 723
    sun.awt.image.GifImageDecoder.produceImage() line: 247
    sun.awt.image.InputStreamImageSource.doFetch() line: 269
    sun.awt.image.ImageFetcher.fetchloop() line: 212
    sun.awt.image.ImageFetcher.run() line: 176
  ]
}
...

答案2

得分: 1

如果这是您的代码,您可以在构造对象时简单地构造一个异常:

public class MyObject {
   public final Exception creationPoint = new Exception();

   ...
}

然后,creationPoint.printStackTrace() 将会打印出创建点(或者您可以调用 getStackTrace() 在程序中进行查询)。正如 GhostCat 所指出的,收集堆栈跟踪(这发生在构造异常对象时)当然会对性能产生影响,因此您通常会谨慎地使用这种技术来调查相对较少生成的对象的特定问题。

英文:

If it's your code, you can simply construct an Exception at the time of constructing the object:

public class MyObject {
   public final Exception creationPoint = new Exception();

   ...
}

Then, creationPoint.printStackTrace() will print the creation point (or you can call getStackTrace() to query it programmatically). As GhostCat points out, collecting the stack trace (which happens on construction of the Exception object) of course has a performance hit, so you would generally use this technique judiciously to investigate a specific issue with objects that are generated relatively infrequently.

答案3

得分: 1

由于效率问题,无法为任何对象收集堆栈跟踪并将该信息与对象一起存储。

收集堆栈跟踪信息是昂贵的,无法在正常程序执行的情况下“大规模”完成这项工作。请记住,堆栈跟踪的主要目的是在异常发生后收集信息。

除此之外,这在概念上也是错误的。如果您只谈论很少的特定对象,那么适当的方法是仔细研究创建这些对象的代码路径,可能要求创建对象的代码进行广泛记录。但是,如果您确实谈论许多不同类型的对象,那么您的要求更表明您的代码中整体记录概念不足。请集中精力解决这部分。

英文:

Collecting a stack trace for any object, and storing that information with the object that simply isn't possible in an efficient manner.

Collecting stack trace information is expensive, and there is no way to do that "on scale", as part of normal program execution. Keep in mind that the primary purpose of stack traces is to collect that information after an exception occurred.

Beyond that, it is also conceptually wrong. If you only talk about very few specific objects, then the appropriate approach would be to carefully study the paths in your code that create these objects, and maybe have the code that creates objects do extensive logging. But if you really talk about many different sort of objects, then your request rather implies that the overall logging concept in your code is insufficient. Focus on that part then.

答案4

得分: 1

JFR可能是你需要的,这个工具可以在对象被创建时捕获堆栈信息,但似乎只捕获部分对象。

英文:

JFR may be what you need, the tool can capture stack information when an object is created, but it seems to capture only part of the all objects.

huangapple
  • 本文由 发表于 2020年8月30日 20:03:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/63657220.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定