Java 性能调优实战
刘超
前金山软件技术经理
59174 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 49 讲
开篇词 (1讲)
模块一 · 概述 (2讲)
结束语 (1讲)
Java 性能调优实战
15
15
1.0x
00:00/00:00
登录|注册

20 | 答疑课堂:模块三热点问题解答

出列
入列
构造函数
ConcurrentLinkedQueue
SynchronousQueue
DelayQueue
PriorityBlockingQueue
LinkedBlockingQueue
ArrayBlockingQueue
查看线程堆栈的运行情况
常用参数
监测具体线程的上下文切换
参数解释
监控进程上下文切换情况
非阻塞队列
阻塞队列
JDK工具之jstack命令
Linux命令行工具之pidstat命令
Linux命令行工具之vmstat命令
多线程队列
监测上下文切换异常的命令排查工具
内容:
主题:Java多线程性能调优
作者:刘超
Java多线程性能调优之热点问题答疑

该思维导图由 AI 生成,仅供参考

你好,我是刘超。
不知不觉“多线程性能优化“已经讲完了,今天这讲我来解答下各位同学在这个模块集中提出的两大问题,第一个是有关监测上下文切换异常的命令排查工具,第二个是有关 blockingQueue 的内容。
也欢迎你积极留言给我,让我知晓你想了解的内容,或者说出你的困惑,我们共同探讨。下面我就直接切入今天的主题了。

使用系统命令查看上下文切换

在第 15 讲中我提到了上下文切换,其中有用到一些工具进行监测,由于篇幅关系就没有详细介绍,今天我就补充总结几个常用的工具给你。

1. Linux 命令行工具之 vmstat 命令

vmstat 是一款指定采样周期和次数的功能性监测工具,我们可以使用它监控进程上下文切换的情况。
vmstat 1 3 命令行代表每秒收集一次性能指标,总共获取 3 次。以下为上图中各个性能指标的注释:
procs
r:等待运行的进程数
b:处于非中断睡眠状态的进程数
memory
swpd:虚拟内存使用情况
free:空闲的内存
buff:用来作为缓冲的内存数
cache:缓存大小
swap
si:从磁盘交换到内存的交换页数量
so:从内存交换到磁盘的交换页数量
io
bi:每秒从块读取数据的量
bo:每秒写入块数据的量
system
in:每秒中断数
cs:每秒上下文切换次数
cpu
us:用户 CPU 使用时间
sy:内核 CPU 系统使用时间
id:空闲时间
wa:等待 I/O 时间
st:运行虚拟机窃取的时间
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了Java多线程性能调优中的热点问题,重点讨论了监测上下文切换异常的常用工具和Java中的多线程队列。作者首先介绍了监测上下文切换异常时可以使用的几个常用工具,包括Linux命令行工具中的vmstat和pidstat命令,以及JDK工具中的jstack命令。通过这些工具,可以监测进程和线程的上下文切换情况,帮助定位性能问题。其次,作者详细介绍了Java中的多线程队列,特别是阻塞队列的使用。阻塞队列在支持生产者和消费者模式中起到了重要作用,作者列举了几种常见的阻塞队列类型,并介绍了它们的特点和适用场景。文章还通过源码分析了ConcurrentLinkedQueue的构造、入列和出列的具体实现,阐述了其基于CAS乐观锁的高并发性能。总的来说,本文内容涵盖了多线程性能调优中的热点问题,以及相关工具和技术的使用方法,对于需要进行多线程性能优化的开发人员具有一定的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Java 性能调优实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(13)

  • 最新
  • 精选
  • 张德
    老师 Disruptor是不是比ConcurrentLinkedQueue性能更强呢???

    作者回复: 对的,Disruptor是一款性能更高的有界队列,利用了生产者消费者模式实现,并采用无锁算法、避免伪共享、RingBuffer等优化手段提升该队列框架性能。

    2019-07-15
    22
  • -W.LI-
    老师好!FGC正常情况多久一次比较合适啊?我们项目1.2天一次FGC老年代给了3G年轻代1G想吧年轻代给多点。有个定时任务,2小时一次用的线程池。给了40个线程并发请求4K次。设置了空闲回收策略回收核心线程。现在就是定时任务,每次都新建40个线程一张吃老年代内存。不设置回收这些线程不实用的那个吧小时就一直阻塞。怎么处理比较合适

    作者回复: GC在核心业务应用服务中越久发生越合适,且GC的时间不要太长。一般生产环境的FGC几天一次是比较正常的。40个线程是不是设置太大了,建议调小一些,当然需要你们具体压测验证下调小后的性能情况。 年轻代可以调大一些,如果年轻代太小,当MinorGC时,发现年轻代依然存活满对象,新的对象可能将无法放入到年轻代,则会通过分配担保机制提前转移年轻代的存活对象到老年代中,这样反而会增加老年代的负担。默认情况下老年代和新生代是2:1。建议没有特殊情况,不要固定设置老年代和新生代。

    2019-07-04
    19
  • Liam
    我有2个问题想请教老师: 1 系统出现问题时我们一般会首先关注资源的使用情况,什么情况下可能是是上下文切换过多导致的呢?CPU消耗过高? 2 ConcurrentLinkedQueue是非阻塞的,是否意味着它会消耗过多的CPu

    作者回复: CPU消耗过高会引起上下文切换的增加,但并不代表这个就不正常了。正常情况下上下文切换在几百到几千,高峰时段会上升至几万,甚至几十万。 如果上下文长时间处于高位,这个时候我们就要注意了,这种情况有可能是某个线程长期占用CPU,例如之前我提到过的正则表达式出现的严重的回溯问题,就会在某一次回溯时,一直占用CPU,CPU的使用率高居不下,会导致上下文切换激增。 另外一种情况,就是之前你们的业务在高峰值出现的上下文切换在某个值,但是在业务迭代之后,高峰期的上下文切换的值异常高于之前的监控值。比如,我之前说的线程大小调整,导致了高峰期的上下文高出了十几倍之多。 ConcurrentLinkedQueue CAS操作会消耗CPU,但会及时释放,这不足以影响到系统的整体性能。

    2019-07-04
    7
  • Dowen Liu
    LinkedBlockingQueue为什么会比ArrayBlockingQueue 快?我记得ArrayBlockingQueue内部应该是循环数组的方式,没有数据搬移和复制的。

    作者回复: LinkedBlockingQueue实现了读写锁分离,所以在一些场景下要比ArrayBlockingQueue快。ArrayBlockingQueue就是正常的锁实现,没有使用复制

    2020-03-18
    5
  • 咬你
    老师,通过vmstat参数获取的参数,可否结合一些真实场景,分析下什么样的数据范围属于正常范围,出现什么样的参数,我们就需要重点关注

    作者回复: 一般系统出现性能瓶颈,可以结果上下文切换指标进行分析。在之前15讲中,我已经通过一个真实案例讲解了,可以参考下,有什么问题欢迎沟通。

    2019-07-04
    2
  • 徐云天
    云里雾里的:有篇文章详解了ConcurrentLinkedQueue https://www.jianshu.com/p/08e8b0c424c0
    2021-11-10
    2
  • 打卡+点赞
    2019-09-10
    1
  • 白不吃
    CAS是不是比加锁的方案,更消耗CPU资源一些
    2022-03-14
  • 渔村蓝
    一个不存储多个元素的阻塞队列,每次进行放入数据时, 必须等待相应的消费者取走数据后,才可以再次放入数据。都不存储多个了,还哪来的先进先出?
    2021-07-06
  • 惘 闻
    Node t = tail, p = t; p和t都是指向的tail指向的堆空间. p.casNext 修改的是tail节点的下一个节点. 为什么修改下一个节点之后就会出现p!=t的情况呢?这俩不还是tail指向的堆内存空间吗? 我好晕啊老师...
    2020-12-29
收起评论
显示
设置
留言
13
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部