分享一个新出炉的JVM里不痛不痒的BUG(Attach机制相关)
本文来自: PerfMa技术社区
概述
老早之前写过一篇文章,关于attach机制的,可以看下这篇老文章了解一下JVM源码分析之Attach机制实现完全解读,比如大家常用的jstack,jmap等工具的主要原理都和attach机制有关,在JVM里处理这些命令的线程主要是Attach Listener
这个线程,这个线程在JVM里是唯一的,我之前也一直以为是唯一的,但是我们同事最近在做一个线程分析产品的时候,发现我们抓到了多个Attach Listener
线程,这让我也很疑惑,我第一感觉是不可能,肯定是数据抓错了,直到亲眼看到了两个同名的Attach Listener
线程我才不得不相信原来还真有这种情况。
问题分析
不过从Attach Listener
的实现来看,它设计的初衷不应该是一个多线程的设计,于是我昨晚上又翻了一遍代码,发现还真可能存在这种情况。举个栗子,当我们很多人同时执行jstack的时候,就可能会发生,当然有个前提是之前都没有做过任何和attach相关的操作。
Attach Listener
线程默认情况下不会在JVM启动的时候就创建,当然也有一个JVM参数可以指定在JVM启动的时候就启动这个线程,这个就不会存在我们今天讨论的这个问题了,这个JVM参数是-XX:+StartAttachListener
。
当我们在运行时触发attach机制的时候,首先会通过Signal Dispatcher
线程来创建Attach Listener
线程,代码如下:
在上面的圈起来的init方法里会创建Attach Listener
线程,但是在init方法执行之前会通过_initialized
属性来判断是否需要创建线程,而_initialized
设置为true是在attach_listener_thread_entry
里,这个是Attach Listener Thread
的entry,也就是当这个线程执行的时候执行的方法。
但是在设置_initialized=true
之前,如果有多个请求信号发出了(比如同时又很多jstack命令触发),可能会创建多个Attach Listener
,因为Signal Dispatcher
和Attach Listener
线程是异步执行的。
问题复现
为了让效果更明显,我们可以在hotspot里修改下代码重新编译下再跑demo
在上面函数里加上圈起来的这段代码,表示在设置_initialized
属性之前停留15s,当进程起来之后,不断执行jstack <pid>
,最终将会看到有非常多的Attach Listener
线程
其实问题的根本就是有一个空档期(设置_initialized
为true之前)可能存在多次创建线程的可能。
总结
总的来说,创建Attach Listener
线程是通过Signal Dispatcher
线程来创建的,但是决定Signal Dispatcher
是否可以重复创建Attach Listener
线程的标记是在某个Attach Listener
线程里设置的,如果没有及时设置该标记,就可能存在创建多个Attach Listener
线程的情况。
一起来学习吧:
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
物联网应用托管服务应用升级的方法有哪些?
云栖号快速入门:【点击查看更多云产品快速入门】不知道怎么入门?这里分分钟解决新手入门等基础问题,可快速完成产品配置操作! 应用升级 对于一个已经上线的应用,如何针对镜像、数据模型、应用配置升级,并让已经部署的应用实例(包括已经售卖给客户的实例)进行更新。当然,不同的应用类型,升级路径不完全相同。本文将相关的各个过程串联一遍,便于用户理解。 1. 实力分发型托管应用 1.1 提交新版本镜像提交新版本到镜像仓库后,在镜像版本管理页面可以看到新版本的镜像信息。 1.2.更新已上线配置在应用配置的“已上线版本列表”,找到要升级的应用配置点击“管理”进入配置管理页面。 1.2.1 镜像升级选择“更新镜像”,针对当前配置中的所有自研节点,首先输入版本说明(这个信息很重要,这是已部署用户获取新版本信息的重要渠道)。点击“下一步”进入升级配置页面。选择 数据模型 > 添加数据模型 ,进入模型声明页面,在列表中,除了选择要声明的模型之外,还要选择“版本”、“数据权限”、“订阅”。其中,数据权限有三种:“查”、“增 | 查”、“增 | 删 | 改 | 查”,分别对应不同的操作类型。模型修改完成后,选...
- 下一篇
Spring Cloud 系列之 Apollo 配置中心(一)
背景 随着程序功能的日益复杂,程序的配置日益增多:各种功能的开关、参数的配置、服务器的地址等等。 对程序配置的期望值也越来越高:配置修改后实时生效,灰度发布,分环境、分集群管理配置,完善的权限、审核机制等等。 在这样的大环境下,传统的通过配置文件、数据库等方式已经越来越无法满足开发人员对配置管理的需求。 Apollo 配置中心应运而生!Apollo - 一个可靠的配置管理系统。 Apollo 介绍 Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。服务端基于 Spring Boot 和 Spring Cloud 开发,打包后可以直接运行,不需要额外安装 Tomcat 等应用容器。 Apollo 支持 4 个维度管理 Key-Value 格式的配置: application (应用) environment (环境) cluster (集群) namespace (命名空间 Namespace 是配置项的集合,类似于一个配置文件的概念)...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS8编译安装MySQL8.0.19
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2整合Redis,开启缓存,提高访问速度
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Docker使用Oracle官方镜像安装(12C,18C,19C)