GC 为什么要挂起用户线程? 什么愁什么怨?
GC 为什么要挂起用户线程? 什么愁什么怨?

前言
JVM 系列文章的第一篇。敬请期待后续。
故障描述
某年某月某日 上午,线上发生故障,经过排查,发现某核心服务 Dubbo 接口超时。

故障根源
查看该服务监控指标,发现该服务 FullGC 次数过于频繁,简直要上天了。那也难怪接口会超时了。
那么为啥 FullGC 次数太多会造成接口超时呢?
因为 GC 停顿。 FullGC 时会产生GC停顿,也叫 stop the world。简称 STW ,是指在执行垃圾收集算法时,用户线程都被挂起。这也不难理解为啥 频繁 FullGC 会引起服务超时了。
深入探究
那么为什么会引起频繁FullGC 呢?
回答这个问题之前,先了解下,有哪些情况会触发 Full GC ?
- 老年代内存空间不足时,会触发 FullGC.
- 永久代/metaspace 内存空间不足时,也会触发FullGC.
- 显示调用 GC,System.gc().(会建议jvm GC,但是不一定会GC).
产生 FullGC 的基本原因就上面三种。
故障服务就是创建很多对象,无法回收,导致内存不足,然后 GC 回收不了时,就会引起频繁 FullGC 了。
复现故障
根据内存不足创建对象会引起 FullGC 的原理,写了一个 Demo ,观察GC 情况。
代码如下:

代码很简单,就是让上次创建的对象可以被回收,然后继续创建对象,然后链接到根结点,使其不会被回收。demo 地址
使用启动参数 -Xms512m -Xmx512m 设置堆内存大小。
启动 Demo ,然后发起请求,观察GC 情况。
首先,使用命令 jps -l 查看进程ID

然后使用 jstat 命令查看GC信息 (jstat 命令详解):

上图可以看到 正在不停的进行 Full GC.

上图可以看出,老年代,以及元数据区 内存空间已满,这也是 不停 Full GC 的原因。
再看我发出的请求:

过去这么久,依然没有结果。
使用 jstack 命令查看 线程状态,发现 用户线程已经被挂起。

不难看出,频繁的 FullGC 已经影响到了应用的正常运行。
结束语
了解 JVM 还是很有必要的。CURD 不觉得什么,问题来临时就可以so easy 了。

GC 为什么要挂起用户线程? 什么愁什么怨?的更多相关文章
- 进程?线程?多线程?同步?异步?守护线程?非守护线程(用户线程)?线程的几种状态?多线程中的方法join()?
1.进程?线程?多线程? 进程就是正在运行的程序,他是线程的集合. 线程是正在独立运行的一条执行路径. 多线程是为了提高程序的执行效率.2.同步?异步? 同步: 单线程 异步: 多线程 3.守护线程? ...
- JVM内的守护线程Deamon与用户线程User Thread
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6561771.html 一:守护线程Daemon 守护线程:Daemon在希腊神话中解作“守护神”,顾名思义就 ...
- java 用户线程和守护线程
在Java中通常有两种线程:用户线程和守护线程(也被称为服务线程)通过Thread.setDaemon(false)设置为用户线程通过Thread.setDaemon(true)设置为守护线程线程属性 ...
- Java用户线程和守护线程
今天看Java一个关于多线程返回值方式的示例,发现一个自己不太能理解的问题,就是在主线程中启动了几个工作线程,主线程中也没有join,工作线程居然也是正常输出了回调的结果.这个跟linux C++下的 ...
- java中线程分两种,守护线程和用户线程。
java中线程分为两种类型:用户线程和守护线程. 通过Thread.setDaemon(false)设置为用户线程: 通过Thread.setDaemon(true)设置为守护线程. 如果不设置次属性 ...
- rt-thread 低优先级线程挂起高优先级线程失败
@2019-01-13 [小记] 使用rt-thread线程管理功能时,低优先级线程挂起高优先级线程失败,高优先级线程或同等优先级线程挂起低优先级线程则成功.
- MySQL 用户连接与用户线程
本文转载自公众号数据库随笔,作者happypig 微信看起来麻烦 pig已经好长一段时间没有分享文章了,有点对不起订阅的朋友.最近在做比较复杂跟困难的事情,也并不一定最终会有成果,因此必须对此沉默. ...
- 【java多线程】用户线程和守护线程的区别
java中线程分为两种类型:用户线程和守护线程.通过Thread.setDaemon(false)设置为用户线程:通过Thread.setDaemon(true)设置为守护线程.如果不设置次属性,默认 ...
- 使用makecontext实现用户线程【转】
转自:http://blog.csdn.net/cyberlabs/article/details/6920138 使用makecontext实现用户线程 现代Unix系统都在ucontext.h中提 ...
随机推荐
- pytorch lstm crf 代码理解
好久没有写博客了,这一次就将最近看的pytorch 教程中的lstm+crf的一些心得与困惑记录下来. 原文 PyTorch Tutorials 参考了很多其他大神的博客,https://blog.c ...
- Java中方法的格式
[修饰符] 返回值类型 方法名([参数类型 形式参数1,参数类型 形式参数2,……]) { 执行语句; [return 返回值;]//需要的话 } 参数列表(参数的类型 ...
- PHP Warning: Module 'json' already loaded in Unknown on line 0
Zend加密文件.启动服务器后无法正常运行加密后的文件.处理方法: 某台服务器上跑着php 5.3.8,线上服务运行正常. 某天拆分php错误日志时,发现其中有一段连续的错误信息. [14-Feb ...
- C# winforms 输入颜色转换颜色名
本文告诉大家如何输入颜色,如0xFFFF8000转换为 Orange 在 winforms 程序 可以使用下面代码转换 public static class HexColorTranslator { ...
- 2018-2-13-win10-uwp-获取指定的文件-AQS
title author date CreateTime categories win10 uwp 获取指定的文件 AQS lindexi 2018-2-13 17:23:3 +0800 2018-2 ...
- vue-learning:34 - component - 内置组件 - 缓存组件keep-alive
vue内置缓存组件keep-alive <keep-alive>标签内包裹的组件切换时会缓存组件实例,而不是销毁它们.避免多次加载相应的组件,减少性能消耗.并且当组件在 <keep- ...
- CSS3侧栏滑出简单实现
使用css3 的 animation 属性实现的点击滑出侧栏 <!DOCTYPE html> <html lang="en"> <head> & ...
- AutoHotKey 用打码的快捷键
本文告诉大家如何使用 AutoHotKey 将 - 键默认输入的时候是下划线,因为使用下划线在写代码的时候是用在私有字段,而 - 很少使用 我打码经常需要使用下划线_而下划线需要按shift+- 两个 ...
- WindowsDOS命令添加/创建/修改/删除服务
添加服务 sc <server> create [service name] [binPath= ] <option1> <option2>... 在注册表和服务数 ...
- luoguP4313 文理分科
luoguP4313 文理分科 复习完之后做了道典型题目. 这道题条件有点多 我们逐个分析 如果没有\(sameart\)或者\(samescience\)的限制,就是一个裸的最大权闭合子图的问题了 ...