java - 使用 async-profiler 和 perf 测量 DirectByteBuffer

标签 java linux jvm perf async-profiler

我正在使用 async-profiler 和 perf,并决定测量 DirectByteBuffer 的内核 Activity 磁盘IO。下面是代码(用 Scala 编写,但其 Java 版本应该很明显):

val path = Paths.get("/tmp/test")

val buffer = ByteBuffer.allocateDirect(4096 * 4096)

def main(args: Array[String]): Unit = {
  var fullReadsCount = 0
  while (true) {
    var bytesRead = 0
    var ch: SeekableByteChannel = null
    try {
      ch = Files.newByteChannel(path)
      while (bytesRead >= 0) {
        bytesRead = ch.read(buffer)
        buffer.clear()
      }
    } finally {
      if (ch != null)
        ch.close()
    }
    fullReadsCount += 1
    if(fullReadsCount % 100 == 0) println(fullReadsCount)
  }
}

我多次运行此代码并执行了 perfasync-profiler并注意到以下结果:

  1. 异步分析器

    $~/profiler.sh -i 28169 -d 30 <pid>
     //.... stack traces ommited
         ns  percent  samples  top
    
    264788732   61.02%     9317  copy_user_enhanced_fast_string_[k]
     41510919    9.57%     1467  generic_file_read_iter_[k]
      9333863    2.15%      331  find_get_entry_[k]
      4181131    0.96%      148  __radix_tree_lookup_[k]
      4057194    0.94%      143  copy_page_to_iter_[k]
      1860485    0.43%       63  __d_lookup_rcu_[k]
      1610407    0.37%       50  _raw_spin_unlock_irqrestore_[k]
    
  2. 性能 sudo perf record -F 31499 -g -p <pid> -- sleep 30

enter image description here

平均而言,在我所做的所有运行中,我注意到 copy_user_enhanced_fast_string perf 中的百分比不同和async-profiler 61.02%77.65%

问题:为什么 copy_user_enhanced_fast_string 的百分比不同采样者perfasync-profiler ?我试图提供相同的条件(频率和采样周期,并且我没有同时运行两个分析器。31499 Hz ≈ 28169 纳秒)。

或者我对结果的解释是错误的?

最佳答案

所选的分析间隔(28 μs)太短。
检查 dmesg - 可能有类似的内核警告

perf interrupt took too long (18047 > 18000), lowering kernel.perf_event_max_sample_rate to 25000

async-profilerperf 的不同之处在于处理 PMU 事件的机制。 perf 只是在环形缓冲区中收集样本,而 async-profiler 向进程发送信号以调用特定于应用程序的回调。通常,用户没有明显的差异,但当分析频率过高时,信号可能会引入额外的噪声并影响进程调度。

我建议将分析间隔增加到至少 100 μs (10000 Hz)。这应该会使测量更加可靠。

关于java - 使用 async-profiler 和 perf 测量 DirectByteBuffer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52430569/

相关文章:

python - 停止 JVM 后,无法再次启动它

java - 自动化 Flash 应用程序

java - 如何在 Java 注释处理器中获取正确的 JavaFileManager?

java - android - RealmRecycle View 上的 java.lang.NoClassDefFoundError

linux - 数据库未打开错误 ORA-01109

java - 对 Permgen 空间这种行为的解释

java - Android 测验应用程序在更新分数时崩溃

java - Unicode 适用于 Windows 但不适用于 Red Hat Linux : Java

android - 使用命令行linux安装android sdk

java - Java实时应用的纵向扩展