我想为Java开发某种反向调试器(在执行过程中可以退一步)。要做到这一点,我必须知道JVM的初始状态(这可以很容易地通过核心转储获得)。然后,我必须拦截JVM正在执行的每一个内存访问,这样我就可以得到JVM在执行过程中所做的事情的时间线,这样我就可以重建JVM的每个状态。
因此,我需要一种方法来拦截内存访问,但是使用低性能开销的,这意味着解决方案不应该给JVM的执行增加超过200-300%的开销,这已经是很多了。
我脑海中浮现的一些想法:
发布于 2020-05-21 06:54:36
实际上,您希望监视Java对象的更改。在低于JVM的级别上跟踪内存更改是一种选择。最大的精度可以通过
对于快照,您可以使用
ptracefork-based异步快照(利用内存在写复制,主进程不必挂起)
该选项的缺点是,您还必须跟踪与Java堆本身无关的写操作(JVM内部、垃圾收集、监视器、库、.)。影响Java堆的写入表示在任何给定时间进程中发生的所有写入的子集。另外,如果没有实际的JVM代码,那么从那些进程快照/转储中提取实际的Java对象就不那么简单了。
在JVM级别上监视变化,一个更有利的策略,可以达到最大的精度。
对于快照,您可以使用
IterateThroughHeap和/或FollowReferences的自定义堆快照HotSpotDiagnosticMXBean mxbean = ManagementFactory.newPlatformMXBeanProxy(
ManagementFactory.getPlatformMBeanServer(),
"com.sun.management:type=HotSpotDiagnostic",
HotSpotDiagnosticMXBean.class);
mxbean.dumpHeap("dump.hprof", true);“正确”方法取决于所需的性能特征、目标平台、可移植性(它是否依赖于特定的JVM实现/版本)和精度/分辨率(快照/抽样聚合写入与记录每个单独写入的检测)。
就性能而言,在JVM级别上进行监视往往更有效率,因为只有实际的Java堆写入才需要考虑。将监控解决方案集成到VM中并利用GC写屏障可能是一种低开销的解决方案,但也是可移植性最小的解决方案(与特定的JVM实现/版本相关联)。
如果您需要记录每一个单独的写入,那么您必须选择检测路径,并且很可能会产生很大的运行时开销。您不能聚合写入,因此没有优化潜力。
在采样/快照方面,实现JVMTI代理可能是一个很好的折衷方案。它提供了高度的可移植性(与许多JVM一起工作)和高度灵活性(可以根据您的需要定制迭代和处理,而不是依赖标准的HPROF堆转储)。
https://stackoverflow.com/questions/61853528
复制相似问题