点击上方“方志朋”,选择“设为星标”

回复”666“获取新整理的面试文章

# 前言

标题没有看错,真的是让我写个 bug!

刚接到这个需求时我内心没有丝毫波澜,甚至还有点激动。这可是我特长啊;终于可以光明正大的写 bug 了????。

先来看看具体是要干啥吧,其实主要就是要让一些负载很低的服务器额外消耗一些内存、CPU 等资源(至于背景就不多说了),让它的负载可以提高一些。

# JVM 内存分配回顾

于是我刷刷一把梭的就把代码写好了,大概如下:

写完之后我就在想一个问题,代码中的 mem 对象在方法执行完之后会不会被立即回收呢?我想肯定会有一部分人认为就是在方法执行完之后回收。

我也正儿八经的去调研了下,问了一些朋友;果不其然确实有一部分认为是在方法执行完毕之后回收。

那事实情况如何呢?我做了一个试验。

我用以下的启动参数将刚才这个应用启动起来。

java -Djava.rmi.server.hostname=10.xx.xx.xx -Djava.security.policy=jstatd.all.policy -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=8888  -Xms4g -Xmx4g  -jar bug-0.0.1-SNAPSHOT.jar

这样我就可以通过 JMX 端口远程连接到这个应用观察内存、GC 情况了。


如果是方法执行完毕就回收 mem 对象,当我分配 250M 内存时;内存就会有一个明显的曲线,同时 GC 也会执行。


这时观察内存曲线。

会发现确实有明显的涨幅,但是之后并没有立即回收,而是一直保持在这个水位。同时左边的 GC 也没有任何的反应。

用 jstat 查看内存布局也是同样的情况。

不管是 YGC,FGC 都没有,只是 Eden 区的使用占比有所增加,毕竟分配了 250M 内存嘛。

那怎样才会回收呢?

我再次分配了两个 250M 之后观察内存曲线。

发现第三个 250M 的时候 Eden 区达到了 98.83% 于是再次分配时就需要回收 Eden 区产生了 YGC。

同时内存曲线也得到了下降。

整个的换算过程如图:

由于初始化的堆内存为 4G,所以算出来的 Eden 区大概为 1092M 内存。

加上应用启动 Spring 之类消耗的大约 20% 内存,所以分配 3 次 250M 内存就会导致 YGC。

再来回顾下刚才的问题:

mem 对象既然在方法执行完毕后不会回收,那什么时候回收呢。

其实只要记住一点即可:对象都需要垃圾回收器发生 GC 时才能回收;不管这个对象是局部变量还是全局变量。

通过刚才的实验也发现了,当 Eden 区空间不足产生 YGC 时才会回收掉我们创建的 mem 对象。

但这里其实还有一个隐藏条件:那就是这个对象是局部变量。如果该对象是全局变量那依然不能被回收。

也就是我们常说的对象不可达,这样不可达的对象在 GC 发生时就会被认为是需要回收的对象从而进行回收。

在多考虑下,为什么有些人会认为方法执行完毕后局部变量会被回收呢?

我想这应当是记混了,其实方法执行完毕后回收的是 栈帧。

它最直接的结果就是导致 mem 这个对象没有被引用了。但没有引用并不代表会被马上回收,也就是上面说到的需要产生 GC 才会回收。

所以使用的是上面提到的对象不可达所采用的可达性分析算法来表明哪些对象需要被回收。

当对象没有被引用后也就认为不可达了。

这里有一张动图比较清晰:

当方法执行完之后其中的 mem 对象就相当于图中的 Object5,所以在 GC 时候就会回收掉。

# 优先在 Eden 区分配对象

其实从上面的例子中可以看出对象是优先分配在新生代中 Eden 区的,但有个前提就是对象不能太大。

以前也写过相关的内容:

# 大对象直接进入老年代

而大对象则是直接分配到老年代中(至于多大算大,可以通过参数配置)。


当我直接分配 1000M 内存时,由于 Eden 区不能直接装下,所以改为分配在老年代中。

可以看到 Eden 区几乎没有变动,但是老年代却涨了 37% ,根据之前计算的老年代内存 2730M 算出来也差不多是 1000M 的内存。

# Linux 内存查看

回到这次我需要完成的需求:增加服务器内存和 CPU 的消耗。

CPU 还好,本身就有一定的使用,同时每创建一个对象也会消耗一些 CPU。

主要是内存,先来看下没启动这个应用之前的内存情况。

大概只使用了 3G 的内存。

启动应用之后大概只消耗了 600M 左右的内存。

为了满足需求我需要分配一些内存,但这里有点需要讲究。

不能一直分配内存,这样会导致 CPU 负载太高了,同时内存也会由于 GC 回收导致占用也不是特别多。

所以我需要少量的分配,让大多数对象在新生代中,为了不被回收需要保持在百分之八九十。

同时也需要分配一些大对象到老年代中,也要保持老年代的使用在百分之八九十。

这样才能最大限度的利用这 4G 的堆内存。

于是我做了以下操作:

  • 先分配一些小对象在新生代中(800M)保持新生代在90%

  • 接着又分配了 老年代内*(100%-已使用的28%);也就是2730*60%=1638M 让老年代也在 90% 左右。

效果如上。

最主要的是一次 GC 都没有发生这样也就达到了我的目的。

最终内存消耗了 3.5G 左右。

# 总结

虽说这次的需求是比较奇葩,但想要精确的控制 JVM 的内存分配还是没那么容易。

需要对它的内存布局,回收都要有一定的了解,写这个 Bug 的过程确实也加深了印象,如果对你有所帮助请不要吝啬你的点赞与分享。

热门内容:JAVA 线上故障排查完整套路!牛掰!
干掉 "ZooKeeper",阿里为什么不用 ZK 做服务发现?一个牛逼的微服务!
干掉Navicat:这个IDEA的兄弟真香!
一文搞定分布式系统ID生成方案微服务架构下静态数据通用缓存机制最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

明天见(。・ω・。)ノ♡

没错,老板让我写个 BUG!相关推荐

  1. 职业生涯第一次:老板让我写个 BUG!

    作者:crossoverJie image 前言 标题没有看错,真的是让我写个 bug! 刚接到这个需求时我内心没有丝毫波澜,甚至还有点激动.这可是我特长啊:终于可以光明正大的写 bug 了. 先来看 ...

  2. 架构师写的BUG,非比寻常

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 部门新来了个架构师,BAT背景,住在三环,开宝马上班,有车位. 小 ...

  3. CTO 写低级 Bug,致公司 70 GB 数据遭泄露!

    前有"程序员删库跑路",后有 CTO 在网站后台引入 Bug,导致公司 1.5 万账户信息外泄. 整理 | 苏宓 出品 | CSDN(ID:CSDNnews) 近日,据外媒报道,美 ...

  4. 架构师写的BUG,非比寻常!

    往期热门文章: 1.<往期精选优秀博文都在这里了!> 2.一个成都程序猿眼中的成都和天府软件园,先从蚂蚁金服说起- 3.终于把废旧电脑变成了服务器!差点被女票拿去换洗脸盆,真香! 4.如何 ...

  5. 架构师写的 BUG ,非比寻常

    点击上方"五分钟学算法",选择"星标"公众号 重磅干货,第一时间送达 部门新来了个架构师,BAT背景,住在三环,开宝马上班,有车位. 小伙话不多,但一旦说话斩钉 ...

  6. 写了Bug,误执行 rm -fr /*,我删删删删库了,要跑路吗?| 原力计划

    作者 | 小林coding 责编 | 伍杏玲 出品 | CSDN博客 小林在五一节前,想到有 5 天假期,心里开始飘了. 写个简单的 Bash 脚本都不上心了,写完连检查都不检查,直接拖到实体服务器跑 ...

  7. 写了Bug,误执行 rm -fr /*,我删删删删库了,要跑路吗?

    每日英语,每天进步一点点(偷笑): 前言 临近五一节,想到有 5 天假期,小林开始飘了. 写个简单的 Bash 脚本都不上心了,写完连检查都不检查,直接拖到到实体服务器跑. 结果一跑起来,发生不对劲, ...

  8. 百架无人机“失控撞楼”,程序员写的 Bug?

    整理 | 郑丽媛 出品 | CSDN(ID:CSDNnews) 一架无人机坠毁或许并不稀奇,但几十上百架的无人机一起炸机撞楼可太"壮观"了.据网友爆料,1 月 25 日晚间,重庆来 ...

  9. Doug Lea 在 J.U.C 包里面写的 BUG 又被网友发现了......

    作者 | why技术 来源 | why技术(ID:hello_hi_why) 头图 |  CSDN 下载自东方IC BUG描述 一个编号为 8073704 的 JDK BUG,将串联起我的这篇文章. ...

最新文章

  1. seq2seq模型_Bart: Seq2Seq预训练模型
  2. ScriptManager调用 无参数WebService
  3. 实例说明listen()函数第二个参数的意义与用法
  4. nyoj359Delete it
  5. linux deepin/ubuntu 搭nginx文件服务器配置
  6. 美团在Redis上踩过的一些坑-5.redis cluster遇到的一些问题
  7. linux 用 grep 查找单个或多个字符串(关键字)
  8. WCF光芒下的Web Service
  9. 电力拖动自动控制系统_系主任带你看专业 | 电气工程及其自动化、电子科学与技术、信息工程、自动化,优质就业、超高考研、竞赛获奖都在这里……...
  10. Virtio原理简介
  11. CentOS下使用Varnish为网站加速
  12. [SQL Server] Access和SQL Server的数据迁移
  13. 腾讯信鸽推送基本流程和数据的处理流程
  14. 工业相机IO口控制STM32输出PWM波
  15. 【Linux】【操作】Linux操作集锦系列之三——进程管理系列之(一) 进程信息查看
  16. [PyQt] MCV模式学习-0
  17. 程序员被离职赔偿18万,房贷八千,只够还一年半,领导:回来上班
  18. linux查看tomcat在,在陌生Linux环境查看Tomcat服务的方法
  19. HTML5+CSS3 02(表格、表单标签、语义化,字符实体标签)
  20. 奥塔在线:Redis5通过源码进行安装及卸载

热门文章

  1. 9.path Sum III(路径和 III)
  2. bzoj 1787 紧急集合
  3. POJ-2955 Brackets
  4. java学习之匿名内部类与包装类
  5. 1282. Game Tree
  6. 2021-2022-1 线性代数知识点总结的视频
  7. 【工程基础】校招研发工程师笔试题
  8. LeetCode实战:排序链表
  9. LeetCode实战:螺旋矩阵
  10. 技术图文:进一步完善自动化交易系统 - 01