第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定

JVM實(shí)現(xiàn)原理分析之safepoint

標(biāo)簽:
Java

safepoint又称为安全点,它是hotspot等JVM中的一个重要概念。下面我们分部分了解下safepoint是什么、safepoint的作用、safepoint是如何实现的以及作为开发者有哪些需要注意的地方。

safepoint是什么

JVM的主要任务是执行Java程序,而JVM运行时本身也是一个程序,但是为了执行Java程序JVM还有不少辅助工作,比如进行GC、JIT编译等等。一般会把运行在JVM上的用户Java程序称为mutator。

以GC为例,JVM中一般的GC都使用可达性分析,也就是从应用程序的一些GC Root(比如运行中的线程栈里的方法栈帧中本地变量表、操作数表中的引用、静态变量引用等)开始通过引用进行引用图遍历,如果在JVM遍历的过程中mutator也在运行,则mutator则可能会修改这个对象图的引用关系,如果JVM不对这种并发修改进行特殊处理,可能导致一些非可回收对象没有被遍历到,从而被标记成垃圾对象而被错误的回收。

如果要完全并发GC,JVM的实现成本会比较大,并且很多情况下整体的吞吐量是会降低的。(联想下并发编程中cas原子操作和加锁的使用,如果竞争比较激烈使用加锁效率更高,因为能够减少cas循环的cpu消耗)

因此在很多GC收集器中都会有一些StopTheWorld阶段,这个StopTheWorld就是safepoint。在safepoint中不会有mutator操作对象,并且线程栈和heap中每个位置的数据类型也是确定的(比如一个8bit的数据是long还是对象引用)。

一个线程要么在safepoint中,要么不在safepoint中。上面提到的StopTheWorld指的是全局safepoint(针对hotspot),也就是要求所有线程都处于safepoint状态。后面如果没有特别说明safepoint也指的是全局safepoint。

safepoint是如何实现的

JVM如何通知线程进入safepoint

在hotspot实现中safepoint是协作式的,当JVM需要mutator进入safepoint时,会设置一个状态标记表示要进入safepoint了,每个mutator线程都会在合适的时机检查这个状态标记,如果发现需要进入safepoint则会暂停自己。这里的合适的时机的选取,既要不那么频繁,避免增大运行时开销(不能每走一步看一次),也不能太久不检查,避免进入safepoint进入太慢(需要线程们都进入safepoint状态才行,如果有一个线程一直干活不检查safepoint会影响其他线程,毕竟其他线程都在等着)。 如果是compiled code(JIT编译后的代码),JIT会在某些地方插入检查代码,比如方法调用返回和循环跳回的地方。 如果是interpreted code(解释执行),JVM有两个字节码分发表,如果需要进入safepoint,则JVM会切换到有safepoint状态检查的那个分发表上。

各个线程如何检查是否要进入safepoint

为了尽量减少开销,hotspot中safepoint的状态检查的实现方式是读取一个内存值,如果需要进入safepoint,则将这个内存页设置成被保护的,这样就会触发一个page fault,然后就可以通过异常处理进入safepoint了。这种方式比准确读取一个内存值(比如一个boolean数据)要轻量(因为需要内存同步) 大家可能会想到如果一个线程处于sleep

线程在执行JNI代码时也处于safepoint中,并且其他的”阻塞”状态也是在safepoint中,比如Thread.sleep,如果要退出线程要退出safepoint需要JVM允许,这样就不会出现sleep状态的线程在其他线程进入safepoint后突然运行这种情况了。

有哪些会引发safepoint的情况

除了一些GC阶段需要safepoint内执行,其他的比较常见的操作有。

  • revoke bias(偏向锁撤销,如果频繁看到偏向锁撤销可以考虑关闭偏向锁 -XX:-UseBiasedLocking)
  • dump线程栈,无论是通过jstack还是通过jmx的ThreadMXBean.getThreadInfo(maxDepth>0的情况)还是Thread.getAllStackTraces等方法,都会触发safepoint,如果线程非常多则可能导致比较长时间的暂停
  • class redefinition(通过Instrument对象对类进行retransform或redefine)
  • code deoptimization
  • 还有很多其他操作

如何排查safepoint相关问题

在JVM启动参数上增加一些参数可以打印出应用暂停和safepoint相关信息。 如果版本<=jdk8

-XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:+PrintSafepointStatistics -XX:PrintSafepointStatisticsCount=1

如果版本>jdk8

-Xlog:gc*=info::time,tags,tid -Xlog:safepoint=info::time,tags,tid

一个示例

[2020-05-18T09:18:55.978-0800][19459][safepoint    ] Application time: 1.0038747 seconds
[2020-05-18T09:18:55.978-0800][19459][safepoint    ] Entering safepoint region: ThreadDump
[2020-05-18T09:18:55.980-0800][19459][safepoint    ] Leaving safepoint region
[2020-05-18T09:18:55.980-0800][19459][safepoint    ] Total time for which application threads were stopped: 0.0017502 seconds, Stopping threads took: 0.0000312 seconds

这个表示应用线程运行了1.0038747秒后,因为ThreadDump开始进入safepoint,应用线程被暂停了0.0017502秒,暂停这些线程花了0.0000312秒

點(diǎn)擊查看更多內(nèi)容
TA 點(diǎn)贊

若覺得本文不錯(cuò),就分享一下吧!

評(píng)論

作者其他優(yōu)質(zhì)文章

正在加載中
  • 推薦
  • 評(píng)論
  • 收藏
  • 共同學(xué)習(xí),寫下你的評(píng)論
感謝您的支持,我會(huì)繼續(xù)努力的~
掃碼打賞,你說(shuō)多少就多少
贊賞金額會(huì)直接到老師賬戶
支付方式
打開微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊(cè)有機(jī)會(huì)得

100積分直接送

付費(fèi)專欄免費(fèi)學(xué)

大額優(yōu)惠券免費(fèi)領(lǐng)

立即參與 放棄機(jī)會(huì)
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)

舉報(bào)

0/150
提交
取消