gpt4 book ai didi

java - 如何在我的 Java 应用程序中设置 JVM 时间(不是操作系统时间)?

转载 作者:行者123 更新时间:2023-12-05 09:37:20 35 4
gpt4 key购买 nike

我正在设计一个回放测试应用程序,它将重放以前记录的数据并处理数据。我想在我的应用程序中配置日期和时间值,这不会影响操作系统。我发现有一个用于设置 JVM 时区的 JVM 参数,但我找不到类似的日期和时间参数。有可能吗?

问候

最佳答案

更改特定进程的日期/时间的常用方法是使用 LD_PRELOAD trick Hook 相应的系统函数。 . Linux 中有两个基本函数可以获取绝对时间:gettimeofdayclock_gettime .这是一个 example library拦截这两个函数。

不幸的是,上述技巧仅适用于 Linux。但这是另一种专门针对 Java 的可移植解决方案。它依赖于 JVM Tool Interface .

在 OpenJDK 中,所有用于获取当前日期/时间的 Java API 最终都会调用 System.currentTimeMillis()VM.getNanoTimeAdjustment()。后者是提供高分辨率 Clock 的内部 JDK 方法。因此,为了更改 Java 应用程序的日期/时间,调整这两种方法的实现就足够了。

思路如下。

  • JVM TI 代理通过订阅 NativeMethodBind 拦截 native 方法绑定(bind)事件。
  • currentTimeMillisgetNanoTimeAdjustment 调用 NativeMethodBind 时,代理会记住 native 函数的地址并将其替换为自己的地址。
  • 每次调用 Hook 方法时,代理首先委托(delegate)给原始函数,然后将指定的偏移量添加到返回值。

这样一个代理的完整代码是here .

如何编译:

g++ -O2 -fPIC -shared -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -olibfaketime.so faketime.cpp

如何运行:

java -agentpath:/path/to/libfaketime.so=<newtime> MainClass

其中 newtime 是从 Epoch 开始的以毫秒为单位的绝对时间戳,或者(当以 +- 开头时)以毫秒为单位的相对偏移量从当前时间开始。

唯一的问题是 System.currentTimeMillis 是 JVM 内在的。这意味着,JIT 编译的方法可能会跳过调用 JNI 实现(从而跳过我们的钩子(Hook))。为避免这种情况,我们可以使用更多 JVM 选项简单地禁用相应的内部函数:

-XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_currentTimeMillis -XX:CompileCommand=dontinline,java.lang.System::currentTimeMillis

关于java - 如何在我的 Java 应用程序中设置 JVM 时间(不是操作系统时间)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64334569/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com