一道面试题引发的对 Java 内存模型的一点疑问
一道面试题引发的对Java内存模型的一点疑问
问题描述

如上图所示程序,按道理,子线程会通过 num++ 操作破坏 while 循环的条件,从而终止循环,执行最后的输出操作。但在我的多次运行中,偶尔会出现 while 循环一直不结束的场合。像我截图一样,程序一直不终止,JDK7、JDK8 均已试验,均能偶然触发。
回复
[西湖の风]:变量前加个 volatile。
[csyangchsh]:volatile 使用读写屏障强制刷新缓存,如果不加就由 CPU 决定何时刷新。
[sofkyle]:由 CPU 决定何时刷新,那么可以认为,终会有一个时机会去刷新,但是while卡在那一直不刷新。
[你假笨]:和 jit 也是有一定关系的,-Xint 设定解释执行,也可以只关闭 OSR 看看,-XX:-UseOnStackReplacement。
JVM STW 里的 no vm operation 是怎么发生的
问题描述

我们线上应用提供的服务接口突然超时(dubbo服务接口调用耗时最大限制1s),发现gc.log在对应的时间进入了STW,耗时1.526s查看对应的vm.log发现在相对饮的时间有一个no vm operation提示,请教下:no vm operation,这个类型vm具体在做什么操作啊?如何优化?
回复
[你假笨]: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(); } }
几个关键的点,GuaranteedSafepointInterval,timedout,SafepointSynchronize::is_cleanup_needed() 如果上面条件满足,就会发生 no vm operation 的 safepoint 操作。
通过GarbageCollectorMXBean获取到的fgc次数耗时与jstat获取到的不一致
问题描述
-XX:+UseCompressedOops -Xms5g -Xmx5g -XX:PermSize=256M -XX:MaxPermSize=1024m -XX:NewSize=3g -XX:MaxNewSize=3g -XX:+UseCMSInitiatingOccupancyOnly -XX:+PerfDataSaveToFile -XX:SurvivorRatio=10 -Xloggc:/data/dataLogs/gc/gc.log -verbose:gc -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:+CMSClassUnloadingEnabled -XX:+DisableExplicitGC -XX:CMSInitiatingOccupancyFraction=80 -XX:+HeapDumpOnOutOfMemoryError
这是我的 jvm 参数,jstat采集到的ygc次数与mxbean是一致的,fgc的数量大概是mxbean统计到的两倍,但是不到两倍。 对于耗时,jstat采集到的无论是ygc还是fgc均小于mxbean统计到的数据。
回复
[Rookie_267692]:这是因为CMS收集器在MXBean是在每次发生FGC时只会在Sweeping统计一次,而jstat会在InitialMark阶段统计一次,FinalMark阶段统计一次,这样发生一次CMS gc时就会统计两次,所以次数不一致。 gc时间在MXBen中统计的是整个gc从开始到结束时间,jstat统计的是gc在每个阶段实际耗费的时间。

推荐阅读 [ZGC什么时候会进行垃圾回收]
推荐阅读 [GC一些长时间停顿问题排查及解决办法]
一道面试题引发的对 Java 内存模型的一点疑问的更多相关文章
- BAT经典面试题,深入理解Java内存模型JMM
Java 内存模型 Java 内存模型(JMM)是一种抽象的概念,并不真实存在,它描述了一组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段.静态字段和构成数组对象的元素)的访问方式.试图屏 ...
- JVM学习(3)——总结Java内存模型
俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及到的知识点总结如下: 为什么学习Java的内存模式 缓存一致性问题 什么是内存模型 JMM(Java Memory Model)简 ...
- 修复 Java 内存模型,第 1 部分——Brian Goetz
转自Java并发大师Brain Goetz:http://www.ibm.com/developerworks/cn/java/j-jtp02244/ (中文地址) http://www.ibm.co ...
- java内存模型个人理解总结
现阶段线程之间的通讯主要有两种:内存共享和消息传递,而且在java中是采用的内存共享.简单说下内存共享: 假设现在有a线程和b线程,在a和b线程之间的通讯是依靠a线程将相关数据刷新到共享内存,然后b线 ...
- 浅谈Java内存模型
Java内存模型虽说是一个老生常谈的问题 ,也是大厂面试中绕不过的,甚至初级面试也会问到.但是真正要理解起来,还是相当困难,主要这个东西看不见,摸不着.网上已经有大量的博客,但是人家的终究是人家的,自 ...
- 来,了解一下Java内存模型(JMM)
网上有很多关于Java内存模型的文章,在<深入理解Java虚拟机>和<Java并发编程的艺术>等书中也都有关于这个知识点的介绍.但是,很多人读完之后还是搞不清楚,甚至有的人说自 ...
- JVM学习(3)——总结Java内存模型---转载自http://www.cnblogs.com/kubixuesheng/p/5202556.html
俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及到的知识点总结如下: 为什么学习Java的内存模式 缓存一致性问题 什么是内存模型 JMM(Java Memory Model)简 ...
- JVM学习记录-Java内存模型(二)
对于volatile型变量的特殊规则 关键字volatile可以说是Java虚拟机提供的最轻量级的同步机制. 在处理多线程数据竞争问题时,不仅仅是可以使用synchronized关键字来实现,使用vo ...
- 转 Java笔记:Java内存模型
Java笔记:Java内存模型 2014.04.09 | Comments 1. 基本概念 <深入理解Java内存模型>详细讲解了java的内存模型,这里对其中的一些基本概念做个简单的笔记 ...
随机推荐
- leetcode.1266访问所有点的最小时间
平面上有 n 个点,点的位置用整数坐标表示 points[i] = [xi, yi].请你计算访问所有这些点需要的最小时间(以秒为单位). 你可以按照下面的规则在平面上移动: 每一秒沿水平或者竖直方向 ...
- $bzoj2067\ szn$ 二分+贪心
正解:二分+贪心 解题报告: 传送门$QwQ$ 题目大意就说有一棵树,然后要用若干条线覆盖所有边且不能重叠.问最少要用几条线,在用线最少的前提下最长的线最短是多长. 昂首先最少用多少条线这个还是蛮$e ...
- 【记录】.bin文件 到 .vdi文件的转换教程
.bin文件 到 .vdi文件的转换教程 1. 背景 想体验一下 Chrome OS 系统,于是准备在 虚拟机VirtualBox(Mac版) 中安装一下,网上教程非常少,找到如下教程 原贴地址:ht ...
- 曹工说Spring Boot源码(8)-- Spring解析xml文件,到底从中得到了什么(util命名空间)
写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...
- docker+mysql 构建数据库的主从复制
docker+mysql 构建数据库的主从复制 在最近的项目中,决定将项目改造成数据库读写分离的架构,后续会有博文详细讲述我的开发改造,本文主要记录我是如何一步步的构建数据库的主从复制. 为什么使用d ...
- 在Windows Server 2003中搭建DNS服务器
1.安装Windows Server 2003虚拟机 准备好Windows Server 2003的镜像:http://www.downza.cn/soft/184944.html 2.Windows ...
- 让vue-router渲染为指定的标签
<router-link :to="{name:'cart'}" tag="li"> cart </router-link> 在rout ...
- Java 数据结构快速入门
数据结构:栈 简介 栈(stack),又称堆栈,它是运算受限的线性表. 限制 栈(stack)的限制是仅允许在标的一端进行插入和删除操作,不允许在其他任何位置进行添加.查找.删除等操作. 采用该结构的 ...
- python文档字符串(函数使用说明)
关键字: 函数说明.help()函数 1.效果图: 2.代码: # 文档字符串( doc str) 是 函数使用说明 # 用法: 在函数第一行写一个字符串 def fn(*nums): ''' 函数的 ...
- 使用“1”个参数调用“DownloadString”时发生异常:“操作超时”
我今天在终端美化时间遇到一个问题是这样的 使用“1”个参数调用“DownloadString”时发生异常:“操作超时” 然后网我看了下,访问链接属于https的东西,根据直觉我觉得是这样的,是由于访问 ...