java gc:什么编程风格使安全点达到更容易(更快)?

时间:2015-07-04 06:54:34

标签: java garbage-collection

假设我想要帮助垃圾收集器。 在GC中花费更少时间的方法之一是更快地达到安全点。

在启动GC之前,必须将所有线程都停放在安全点。

Safepoint是执行流程中的“特殊位置”,可以安全地停止线程以执行GC。

我希望尽量减少在代码中等待安全点的时间。 什么编码风格将帮助我更快地达到安全点?

什么样的风格让这项任务更加不舒服?

style 下,我指的是语言中的一切,有助于(或阻止)快速“获取”安全点。

示例:

磁盘IO工作是否会使问题更严重?

JNI是否会使问题更严重?

Thread.sleep()会让它更难吗?

同步(..)让它更难吗?

等。

简而言之,哪些java操作和方法会快速“获取”安全点问题?有什么帮助?

1 个答案:

答案 0 :(得分:0)

让我们以此注释开头(来自OpenJDK源代码中的“ src / hotspot / share / runtime / safepoint.cpp”文件):

<form action="{{ url('create') }}" method="post" onsubmit="return validation()">

由此我得出以下结论:

  • 当JVM线程解释字节码时,它可以在任何字节码之后到达安全点。
  • 当JVM线程运行已JIT编译的代码时,其行为取决于JIT编译何时/何地注入指令以轮询“安全点轮询”页面。
  • 运行本机(JNI)线程时,从安全点角度将其忽略。但是,我相信,如果正在进行安全点操作,则某些JNI调用将导致本机线程阻塞。
  • 如果Java线程被阻止(例如,被线程调度程序或I / O syscall调用),或者它更改了状态,则可以继续执行安全点操作。

但这只是回答问题的一部分。问题在于,JIT编译代码中的安全点轮询是由JIT编译器添加的指令完成的。没有指定控制该逻辑的逻辑 1 ,并且易于实现。此外,我听说使用 // Java threads can be in several different states and are // stopped by different mechanisms: // // 1. Running interpreted // The interpreter dispatch table is changed to force it to // check for a safepoint condition between bytecodes. // 2. Running in native code // When returning from the native code, a Java thread must check // the safepoint _state to see if we must block. If the // VM thread sees a Java thread in native, it does // not wait for this thread to block. The order of the memory // writes and reads of both the safepoint state and the Java // threads state is critical. In order to guarantee that the // memory writes are serialized with respect to each other, // the VM thread issues a memory barrier instruction // (on MP systems). In order to avoid the overhead of issuing // a memory barrier for each Java thread making native calls, each Java // thread performs a write to a single memory page after changing // the thread state. The VM thread performs a sequence of // mprotect OS calls which forces all previous writes from all // Java threads to be serialized. This is done in the // os::serialize_thread_states() call. This has proven to be // much more efficient than executing a membar instruction // on every call to native code. // 3. Running compiled Code // Compiled code reads a global (Safepoint Polling) page that // is set to fault if we are trying to get to a safepoint. // 4. Blocked // A thread which is blocked will not be allowed to return from the // block condition until the safepoint operation is complete. // 5. In VM or Transitioning between states // If a Java thread is currently running in the VM or transitioning // between states, the safepointing code will wait for the thread to // block itself when it attempts transitions to a new state. // 和其他内置/内在操作 进行内存复制可能会花费很长时间而没有安全点检查。

关于您的具体示例:

  

磁盘IO的工作是否会带来更多问题?

否。

  

JNI是否使它更具问题性?

否。

  

Thread.sleep()使它变得更难吗?

否。

  

是否已同步(..)使其更难?

否。

关于您的一般问题:

  

什么风格使任务[到达安全点]更加不舒服?

可能应该避免使用递归来避免显式循环的编码样式。


1-我隐约记得它是在向后分支上发生的;例如在任何Java循环中。