求助>JVM STW里的no vm operation是怎么发生的>
20回复
7月前

JVM STW里的no vm operation是怎么发生的



WechatIMG5.jpeg

各位好,请教一个问题
我们线上应用提供的服务接口突然超时(dubbo服务接口调用耗时最大限制1s),发现gc.log在对应的时间进入了STW,耗时1.526s
查看对应的vm.log发现在相对饮的时间有一个no vm operation提示,请教下:
no vm operation,这个类型vm具体在做什么操作啊?
如何优化?

谢谢

jvm使用信息:
jdk8,垃圾回收器是CMS,如果有信息不全请在JVM参数群里联系我,微信:左温

3211 阅读
请先登录,再评论

回复列表

你假笨7月前

safepoint并不是一定要发生了某个VM_OP才会进入的,VMThread本身的执行,就是不断循环,看是否有必要进入safepoint,或者是否要执行一些VM_OP,可以看下这块代码

while (!should_terminate() && _cur_vm_operation == NULL) {
        // wait with a timeout to guarantee safepoints at regular intervals
        bool timedout =
          VMOperationQueue_lock->wait(Mutex::_no_safepoint_check_flag,
                                      GuaranteedSafepointInterval);

        // Support for self destruction
        if ((SelfDestructTimer != 0) && !is_error_reported() &&
            (os::elapsedTime() > SelfDestructTimer * 60)) {
          tty->print_cr("VM self-destructed");
          exit(-1);
        }

        if (timedout && (SafepointALot ||
                         SafepointSynchronize::is_cleanup_needed())) {
          MutexUnlockerEx mul(VMOperationQueue_lock,
                              Mutex::_no_safepoint_check_flag);
          // Force a safepoint since we have not had one for at least
          // 'GuaranteedSafepointInterval' milliseconds.  This will run all
          // the clean-up processing that needs to be done regularly at a
          // safepoint
          SafepointSynchronize::begin();
          #ifdef ASSERT
            if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot();
          #endif
          SafepointSynchronize::end();
        }
        _cur_vm_operation = _vm_queue->remove_next();

        // If we are at a safepoint we will evaluate all the operations that
        // follow that also require a safepoint
        if (_cur_vm_operation != NULL &&
            _cur_vm_operation->evaluate_at_safepoint()) {
          safepoint_ops = _vm_queue->drain_at_safepoint_priority();
        }
      }

几个关键的点,GuaranteedSafepointIntervaltimedoutSafepointSynchronize::is_cleanup_needed()
如果上面条件满足,就会发生no vm operation的safepoint操作

1
回复 你假笨:

spin是0,没法让线程栈打印出来

回复
左温6月前
回复 kong_228640:

超时,你定一个很短的时间。不就模拟出来了么

回复
回复 左温:

我们也有你这个问题,后边有什么进展吗?线程栈应该是在spin超时情况下才会打印吧

回复
查看更多

等回复

左温7月前

3333.png
上下文GC日志

左温7月前

jvm:参数
JAVA_OPTS="-Dfile.encoding=UTF8 -Xms2g -Xmx2g -Xmn1g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -Xss256K -XX:-UseBiasedLocking -XX:SurvivorRatio=8 -XX:MaxDirectMemorySize=1g -XX:+UseConcMarkSweepGC -XX:+ExplicitGCInvokesConcurrent -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=75 -XX:+CMSScavengeBeforeRemark -XX:+PrintPromotionFailure -XX:+PrintCommandLineFlags -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:+PrintSafepointStatistics -XX:PrintSafepointStatisticsCount=1 -XX:+PrintTenuringDistribution -XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:-DisplayVMOutput -XX:LogFile=$LOG_FOLDER/vm.${DATETIME}.log -Ddubbo.application.qos.accept.foreign.ip=false -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+HeapDumpOnOutOfMemoryError -Xloggc:$LOG_FOLDER/gc.${DATETIME}.log -XX:HeapDumpPath=$LOG_FOLDER -DlogHome=$LOG_FOLDER -Dmode=prod -DlogRef=default -Ddisconf.env=prod -Denv=PRO -Dapollo.cacheDir=$BOOT_HOME/apollo/cache -Ddubbo.application.qos.port=20079"