前段时间,一个线上项目忽然很卡,通过监控,发现内存很高,果不其然在几个小时后,OOM。虽说有人很快处理好了。但我还是想站在我的角度,对这件事发表一下自己的观点。

内存溢出,多发生在项目上线后,而且在系统开发阶段和单元测试阶段几乎不被发现。这其实是和开发者习惯有关。譬如一些空的引用,就会占着茅厕不拉屎等等

而要搞明白这个过程,不得不提一下java是如何管理内存的。主要涉及到对象的分配和释放。

在java中,内存分配是由程序完成的,而释放,是由垃圾回收机制自动完成的。

内存分配扯到各种new 对象,此处不多写,主要谈谈GC过程 。

我用idea装了Java VisualVM插件 ,用自己的测试工程启动后,可以看到这样一个界面,说明插件安装成功,已经成功监视到我的工程

我不是来讲这个插件如何使用的,我本人也在学习阶段,所以直接看本文重点

在我第一次看到这个图的时候,恍然大明白,原来之前看的GC分区,就是这么回事。但是过程是什么样的呢,就这个图我做下说明(其实是我自己在网上整理了一下,然后讲出来,加上自己的一些理解)

希望能对和我一样曾经徘徊在GC门口的人一点帮助。

图示,在整个GC过程中,大概有3个历程。

Eden Space:新生

Old Gen:老年

Metaspace:持久代。持久好啊^_^

新生代和老年代之间,有2个Survivor区,图里面为S0,S1.这两个作用是什么,别着急,咱一步步来,要有前戏。

首先当对象被创建的时候,new一个女朋友,是每个程序猿的梦想。但是在这里,女朋友需要从相亲对象不断的跨越山河大海,才能成为女朋友,持续在一起。我开辟一个主任务(系统栈):我要相亲,媒婆给我找一些相亲对象来。于是乎,很多相亲对象被new了出来,要大面撒网嘛。所以很多各种模样的相亲对象就排着队进到Eden区,高的,矮的,胖的,瘦的,瓜子脸,O型腿,什么样的都有。

护卫何在,在。去把这些矮的,胖的,长相怪异的,都给我赶出门外,还有媒婆你下次挑的时候,长点眼睛。Eden:S区默认大小是8:1

于是一些看了一眼,甚至看都没看一眼的垃圾对象被清了出去。剩下的,都还看的过去。全部给我去S0房间待着啊,进行第一轮考核。此刻S1是空的。

此时Eden房间已经闲置了,但是在整个项目运行期间,只要有人进行任何操作,都会不断的有新对象进来到内存中。

所以Eden很快又满了,在经历了S0房间的筛选后,一些人由于思想问题,也要被赶出去,同时呢Eden这一批也有留下的,于是,S0剩下的和Eden剩下的,全都给我去S1待着去,那里会继续审查。为什么这批S0的已经审查过了,还有继续审查呢,那是因为现在网络这么发达,太多东西都可以作假,一次可能瞒混过关,需要进行多次选择。注意此刻S0是空的。(复制、引用计数法。Scavenge GC)

当这批S1的检查完后,去掉一些家底不干净的,还留了一部分,而新的Eden依旧有一批筛选后的,这两部分人,又全部进去S0再次给我检查,身上有胎记的,毛太长的,有狐臭的等等都给我赶出去。此刻S1是空的。(复制、引用计数法。Scavenge GC)

当如此循环多次后,筛选来筛选后,发现某次S0或者S1挤满了,不能再和新的Eden区剩下的人去挤进一个S房间了,系统就认为这批相亲对象,质量很高(对象的引用一直存在),全部移步到Old Gen。此刻S0和S1空了,继续和Eden进行新的循环。

此刻我来到Old Gen,开始逐个进行洗脑,这是个漫长的过程:因为要成为我的女朋友,要心甘情愿的洗衣做饭暖床等等。过了很长一段时间的试恋爱后,Old Gen房间太满了,而且还有很多不同意以上条件的美女们,我不能白养着啊,不合适就走吧,我不是慈善家。都走后门出去啊,别太惹人注目。

此处对应GC中,Eden和S区调整不能腾出足够的空间时,要进行的FULL GC,此时JVM GC停止所有在heap中 运行的线程并执行清除动作。(标记压缩-清除)

而经历了多次FULL GC还留下的,我要把你们纳入后宫,都去Metaspace吧。我在那里等着你们。那里有我喜欢的生活用品,交通工具等。几乎不会改变,只会把一些旧的更换成新的。只要我有肉吃,就少不了你们的汤喝。

有几个点需要强调一下,如果Eden中有极品美女,是可以直接进入到Old Gen的。对应一些大的对象,直接进老年代。

以上只是一些总结,随着学习的深入,我会继续补充。有写错的,欢迎在评论区纠正。哈哈,第一次写这么长。自我鼓励一下

浅谈对java-GC的理解的更多相关文章

  1. 20190608_浅谈go&java差异(三)

    20190608_浅谈go&java差异(三) 转载请注明出处https://www.cnblogs.com/funnyzpc/p/10990703.html 第三节内容概览 多线程通讯(线程 ...

  2. Java-谈谈对Java平台的理解

    问题 谈谈对 Java 平台的理解 Java是解释执行的 这句话对么 程序的编译与解释有什么区别 Java 平台的了解 Java的主要特点是两个, 编写一次到处运行 Write once, run a ...

  3. 浅谈对java中锁的理解

    在并发编程中,经常遇到多个线程访问同一个 共享资源 ,这时候作为开发者必须考虑如何维护数据一致性,在java中synchronized关键字被常用于维护数据一致性.synchronized机制是给共享 ...

  4. 浅谈对java中传参问题的理解

    之前用的c/c++比较多,在c/c++中对于传参类型,无外乎就是传值.传引用.传指针这几种.但在java中,由于没有指针类型,其传参的方式也发生了相应的变化.在网上找了找,按我之前的理解,java中传 ...

  5. 干货,阿里P8浅谈对java线程池的理解(面试必备)

    线程池的概念 线程池由任务队列和工作线程组成,它可以重用线程来避免线程创建的开销,在任务过多时通过排队避免创建过多线程来减少系统资源消耗和竞争,确保任务有序完成:ThreadPoolExecutor ...

  6. 浅谈一下Java String

    相信很多同学使用Java String, Java中的String方法,但是对其中的原理可能有些模糊,那么咱们就针对这块内容进行展开,让更多的同学理解和知道. public final class S ...

  7. 浅谈:java泛型与dao重用

    在进入今天的主题之前,我们先理解一下什么是泛型: 泛型是java中一种类型,泛型是被参数化的类型. 类型-->class 参数化-->class类型可以是任意参数 泛型存在的意义:泛型可以 ...

  8. 浅谈我对JCS 的理解

    JCS 是Java 中缓存的一种实现,支持将数据缓存到内存和硬盘中,支持设置缓存对象的有效时长. 我认为可以这么理解JCS:客户端向服务器发出请求,服务器就先去缓存中查一下有没有客户端请求的数据,有则 ...

  9. 浅谈用java解析xml文档(一)

    关于xml本身的语法及使用的环境不多说了,网上有很多规则, 然对xml文档进行解析,一般分为四种解析方式,基于java官方文档的Dom 和Sax解析,还有就是基于 第三方jar包的 Jdom 和 Do ...

  10. 浅谈对JIT编译器的理解。

    1. 什么是Just In Time编译器? Hot Spot 编译 当 JVM 执行代码时,它并不立即开始编译代码.这主要有两个原因: 首先,如果这段代码本身在将来只会被执行一次,那么从本质上看,编 ...

随机推荐

  1. Java游戏之碰撞检测

    在进行Java游戏开发时,我们经常会遇到碰撞检测的问题.如坦克大战中,炮弹与坦克相遇发生爆炸:守卫者游戏中,守卫者发射的箭与怪物相遇使怪物失血:打飞机游戏中,飞机发送的子弹与敌机相遇干掉敌机.这些都需 ...

  2. Same origin policy

    Chrome: Origin null is not allowed by Access-Control-Allow-Origin 的问题 发送 http request 时遇到 error: Ori ...

  3. 【转载】7条便利的ViewState技巧

    32.Seven handy ViewState tips 32.7条便利的ViewState技巧 Every time I have to deal with a classic ASP.NET W ...

  4. 使用frp工具实现内网的穿透以及配置多个ssh和web服务

    frp简介 FRP 项目地址 https://github.com/fatedier/frp/blob/master/README_zh.md frp 是一个可用于内网穿透的高性能的反向代理应用,支持 ...

  5. composer查看安装情况

    composer install --no-progress --profile -vvv

  6. 01—Spring基础配置IOC

  7. Html 标签的事件绑定(转自 MSDN)

    参考 MSDN 网页给 HTML 标签绑定 click 事件: function makeFoldersCollapsible(folderIcon, openFolderIcon, pathToIc ...

  8. Js onmouseover和onmouseout小特效

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...

  9. Python学习日记之正则表达式re模块

    用在线网页测试正则表达式时,JavaScript不支持 零宽度正回顾后发断言 (?<=exp)测试时一直匹配失败 但re模块是支持 (?<=exp) 的 终于脱坑

  10. BackboneJS and UnderscoreJS

     介绍 来自API(backbone能做什么?) 当我们开发含有大量Javascript的web应用程序时,首先你需要做的事情之一便是停止向DOM对象附加数据. 通过复杂多变的jQuery选择符和回调 ...