一 ,GC的概要:

JVM主要管理两种类型内存:堆和非堆,堆内存(Heap Memory)是在 Java 虚拟机启动时创建,非堆内存(Non-heap Memory)是在JVM堆之外的内存。

简单来说,堆是Java代码可及的内存,留给开发人员使用的;非堆是JVM留给自己用的,包含方法区、JVM内部处理或优化所需的内存(如 JIT Compiler,Just-in-time Compiler,即时编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码。

JVM 内存包含如下几个部分:

堆内存(Heap Memory): 存放Java对象

非堆内存(Non-Heap Memory): 存放类加载信息和其它meta-data

其它(Other): 存放JVM 自身代码等

为什么先说JVM堆?

JVM的堆是Java对象的活动空间,程序中的类的对象从中分配空间,其存储着正在运行着的应用程序用到的所有对象。这些对象的建立方式就是那些new一类的操作,当对象无用后,是GC来负责这个无用的对象(地球人都知道)。

JVM堆

(1) 新域:存储所有新成生的对象

(2) 旧域:新域中的对象,经过了一定次数的GC循环后,被移入旧域

(3)永久域:存储类和方法对象,从配置的角度看,这个域是独立的,不包括在JVM堆内。默认为4M。

新域会被分为3个部分:1.第一个部分叫Eden。(伊甸园??可能是因为亚当和夏娃是人类最早的活动对象?)2.另两个部分称为辅助生存空间(幼儿园),我这里一个称为A空间(From sqace),一个称为B空间(To Space)。

二、GC浅谈

**GC基本原理:

Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。所以,Java的内存管理实际上就是对象的管理,其中包括对象的分配和释放。**

GC的工作目的很明确:在堆中,找到已经无用的对象,并把这些对象占用的空间收回使其可以重新利用.大多数垃圾回收的 算法思路都是一致的:把所有对象组成一个集合,或可以理解为树状结构,从树根开始找,只要可以找到的都是活动对象,如果找不到,这个对象就是凋零的昨日黄 花,应该被回收了。

在sun 的文档说明中,对JVM堆的新域,是采用coping算法,该算法的提出是为了克服句柄的开销和解决堆碎片的垃圾回收。它开始时把堆分成一个对象面和多个 空闲面,程序从对象面为对象分配空间,当对象满了,基于 coping算法的垃圾收集就从根集中扫描活动对象,并将每个活动对象复制到空闲面(使得活动对象所占的内存之间没有空闲洞),这样空闲面变成了对象面, 原来的对象面变成了空闲面,程序会在新的对象面中分配内存。

对于新生成的对象,都放在Eden中;当Eden充满时(小孩太多 了),GC将开始工作,首先停止应用程序的运行,开始收集垃圾,把所有可找到的对象都复制到A空间中,一旦当A空间充满,GC就把在A空间中可找到的对象 都复制到B空间中(会覆盖原有的存储对象),当B空间满的时间,GC就把在B空间中可找到的对象都复制到A空间中,AB在这个过程中互换角色,那位客官说 了:拷来拷去,烦不烦啊?什么时候是头?您别急,在活动对象经过一定次数的GC操作后,这些活动对象就会被放到旧域中。对于这些活动对象,新域的幼儿园生 活结束了。新域为什么要这么折腾?起初在这块我也很迷糊,又查了些资料,原来是这样:应用程序生成的绝大部分对象都是短命的,copying算法最理想的 状态是,所有移出Eden的对象都会被收集,因为这些都是短命鬼,经过一定次数的GC后应该被收集,那么移入到旧域的对象都是长命的,这样可以防止AB空 间的来回复制影响应用程序。实际上这种理想状态是很难达到的,应用程序中不可避免地存在长命的对象,copying算法的发明者要这些对象都尽量放在新域 中,以保证小范围的复制,压缩旧域的开销可比新域中的复制大得多(旧域在下面说)。对于旧域,采用的是tracing算法的一种,称为标记-清除-压缩收 集器,注意,这有一个压缩,这是个开销挺大的操作。垃圾回收主要是对Young Generation块和Old Generation块内存进行回收,YG用来放新产生的对象,经过几次回收还没回收掉的对象往OG中移动,对YG进行垃圾回收又叫做MinorGC,对 OG垃圾回收又叫MajorGC,两块内存回收互不干涉。

二、Gc 流程:

1.当eden满了,触发young GC;

2. GC做2件事:一,去掉一部分没用的object;二,把老的还被引用的object发到survior里面,等下几次GC以后,survivor再放到old里面。

3.当old满了,触发full GC。full GC很消耗内存,把old,young里面大部分垃圾回收掉。这个时候用户线程都会被block。

三、young generation比例越大,不一定最好。

将young的大小设置为大于总堆大小的一半时会造成效率低下。如果设置得过小,又会因为young generation收集程序不得不频繁运行而造成瓶颈。

四、总结

从上面的推导可以得出很多结论,下面是前辈的经验总结与自已的认识

1.JVM堆的大小决定了GC的运行时间。如果JVM堆的大小超过一定的限度,那么GC的运行时间会很长。

2.对象生存的时间越长,GC需要的回收时间也越长,影响了回收速度。

3.大多数对象都是短命的,所以,如果能让这些对象的生存期在GC的一次运行周期内,wonderful!

4.应用程序中,建立与释放对象的速度决定了垃圾收集的频率。

5.如果GC一次运行周期超过3-5秒,这会很影响应用程序的运行,如果可以,应该减少JVM堆的大小了。

6.前辈经验之谈:通常情况下,JVM堆的大小应为物理内存的80%。

五、看案例

jmap -heap 2343

Attaching to process ID 2343, please wait…

Debugger attached successfully.

Server compiler detected.

JVM version is 11.0-b16

using thread-local object allocation.

Parallel GC with 8 thread(s)

Heap Configuration:

MinHeapFreeRatio = 40

MaxHeapFreeRatio = 70

MaxHeapSize = 4294967296 (4096.0MB)

NewSize = 2686976 (2.5625MB)

MaxNewSize = -65536 (-0.0625MB)

OldSize = 5439488 (5.1875MB)

NewRatio = 2 (YG,OG 大小比为1:2)

SurvivorRatio = 8

PermSize = 21757952 (20.75MB)

MaxPermSize = 268435456 (256.0MB)

Heap Usage:

PS Young Generation

Eden Space:

capacity = 1260060672 (1201.6875MB)

used = 64868288 (61.86322021484375MB)

free = 1195192384 (1139.8242797851562MB)

5.148028935546367% used

From Space:

capacity = 85524480 (81.5625MB)

used = 59457648 (56.70323181152344MB)

free = 26066832 (24.859268188476562MB)

69.52120375359195% used

To Space:

capacity = 85852160 (81.875MB)

used = 0 (0.0MB)

free = 85852160 (81.875MB)

0.0% used

~~~~~~~~~~~~~~~~~~~~~~这三块为上面所说的YG大小和使用情况

PS Old Generation

capacity = 2291138560 (2185.0MB)

used = 1747845928 (1666.8757705688477MB)

free = 543292632 (518.1242294311523MB)

76.28722062099989% used

~~~~~~~~~~~~~~~~~~~~~~OG大小和使用情况

PS Perm Generation

capacity = 108265472 (103.25MB)

used = 107650712 (102.6637191772461MB)

free = 614760 (0.5862808227539062MB)

99.43217353728436% used

这台机器简单说YG内存1G,OG内存2G,总内存4G

在这样的配置下,GC运行情况:

jstat -gcutil -h5 2343 4s 100

S0 S1 E O P YGC YGCT FGC FGCT GCT

79.82 0.00 75.34 78.55 99.44 7646 1221.668 398 2052.993 3274.661

0.00 79.52 0.62 78.63 99.44 7647 1221.782 398 2052.993 3274.775 这里发生了一次YG GC,也就是MinorGC,耗时0.12s

0.00 79.52 28.95 78.63 99.44 7647 1221.782 398 2052.993 3274.775

0.00 79.52 46.34 78.63 99.44 7647 1221.782 398 2052.993 3274.775

同时可以看到总共进行了398次Major GC 总耗时2052.993 所以每次Major GC时间为:2052.993/398=5.16秒

这是个很严重的问题,进行Major GC的时候程序会暂停,无法响应,居然会暂停5秒多,这谁都无法接受吧 :)

同样Minor GC进行了7647次,总用时1221.782 平均时间为0.16秒,算是可以接受

再来看看修改配置后:

jmap -heap 14103

Attaching to process ID 14103, please wait…

Debugger attached successfully.

Server compiler detected.

JVM version is 11.0-b16

using parallel threads in the new generation.

using thread-local object allocation.

Concurrent Mark-Sweep GC

Heap Configuration:

MinHeapFreeRatio = 40

MaxHeapFreeRatio = 70

MaxHeapSize = 4294967296 (4096.0MB)

NewSize = 536870912 (512.0MB)

MaxNewSize = 536870912 (512.0MB)

OldSize = 5439488 (5.1875MB)

NewRatio =4 YG:OG 1:4

SurvivorRatio = 8

PermSize = 268435456 (256.0MB)

MaxPermSize = 268435456 (256.0MB)

Heap Usage:

New Generation (Eden + 1 Survivor Space):

capacity = 483196928 (460.8125MB)

used = 428284392 (408.4438247680664MB)

free = 54912536 (52.368675231933594MB)

88.63557841162434% used

Eden Space:

capacity = 429522944 (409.625MB)

used = 404788608 (386.0364990234375MB)

free = 24734336 (23.5885009765625MB)

94.24144010337199% used

From Space:

capacity = 53673984 (51.1875MB)

used = 23495784 (22.407325744628906MB)

free = 30178200 (28.780174255371094MB)

43.77499534970238% used

To Space:

capacity = 53673984 (51.1875MB)

used = 0 (0.0MB)

free = 53673984 (51.1875MB)

0.0% used

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~YG 大小和使用状态

concurrent mark-sweep generation:

capacity = 3758096384 (3584.0MB)

used = 1680041600 (1602.2125244140625MB)

free = 2078054784 (1981.7874755859375MB)

44.70459052494594% used

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~OG 大小和使用状态

Perm Generation:

capacity = 268435456 (256.0MB)

used = 128012184 (122.0819320678711MB)

free = 140423272 (133.9180679321289MB)

47.688254714012146% used

在这个配置下,GC运行情况:

jstat -gcutil -h5 14103 4s 100

S0 S1 E O P YGC YGCT FGC FGCT GCT

47.49 0.00 64.82 46.08 47.69 20822 2058.631 68 22.734 2081.365

0.00 37.91 38.57 46.13 47.69 20823 2058.691 68 22.734 2081.425 这里发生了一次YG GC,也就是MinorGC,耗时0.06s

46.69 0.00 15.19 46.18 47.69 20824 2058.776 68 22.734 2081.510

46.69 0.00 74.59 46.18 47.69 20824 2058.776 68 22.734 2081.510

0.00 40.29 19.95 46.24 47.69 20825 2058.848 68 22.734 2081.582

MajorGC平均时间:22.734/68=0.334秒(上面是5秒多吧) MinorGC平均时间:2058.691/20823=0.099秒(比上面略少)

java在gc正常工作的情况下_Java GC的工作原理相关推荐

  1. 1.什么情况下发生GC

    目录 一:jvm运行时数据区的划分 二:堆区的划分(where) 三:什么情况下发生GC(when) 四:哪些内存需要回收(垃圾对象who) 五:GC如何回收(how) 六:jvm的内存回收过程 七: ...

  2. 如何在不知道密码的情况下解除excel的工作表中的保护

    如何在不知道密码的情况下解除excel的工作表中的保护 在工作过程中经常会遇到打开一个受保护的excel文件,不知道密码只能查看不能进行编辑,那如何在不知道密码的情况下解除excel工作表的保护呢?下 ...

  3. java在gc正常工作的情况下_最新JVM面试题小结,程序猿直呼内行

    这篇文章主要介绍了JVM面试题小结(2020最新版),觉得挺不错的,现在分享给大家,也给大家做个参考. Java内存区域 说一下 JVM 的主要组成部分及其作用? JVM包含两个子系统和两个组件,两个 ...

  4. java switch配合return_关于Java switch语句:关于Java switch语句 – 在每种情况下使用return和省略break...

    鉴于这种方法,这是否代表了一些令人震惊的风格或语义失误: private double translateSlider(int sliderVal) { switch (sliderVal) { ca ...

  5. 038、JVM实战总结:200小时积累,6小时烹制,史上最强图,图解:大厂面试题,Young GC和Full GC分别在什么情况下会发生?

    今天学习本讲,按照艾宾浩斯遗忘曲线应该复习:37 35 31 24 9.建议大家按照遗忘曲线来复习学过的内容. 这是本人花了6个小时,精心绘制的"垃圾回收"活动图,同时进行了文字总 ...

  6. 周末总是被工作打扰_如何在不打扰任何人的情况下问为什么在工作中

    周末总是被工作打扰 我记得几年前的一个晚上,那时我正坐在沙发上和一些朋友一起看电影. 那是在小型翻盖手机的时代,当时根本没有手机. 几杯各种饮料撒在咖啡桌上,当我的朋友雷切尔坐在沙发上时,她随便扔掉了 ...

  7. 史上最强图,图解:大厂面试题,Young GC和Full GC分别在什么情况下会发生?

    在原文基础上重新绘制了一下进行Young GC .Full GC 的条件及处理过程(原文链接 https://blog.csdn.net/dingshuo168/article/details/987 ...

  8. java setquality_Java-在不损失质量的情况下调整图像大小

    给定您的输入图像,注释中第一个链接的答案中的方法(对Chris Campbell表示敬意)将产生以下缩略图之一: (另一个是您使用MS Paint创建的缩略图.很难称其中一个比另一个"更好& ...

  9. java中数组的内存模型_Java如何在内存有限的情况下实现一个超大数组?jvm性能调优+内存模型+虚拟机原理能解决什么样问题...

    在上一篇文章中,小编为您详细介绍了关于<变频器调速问题?三星R458更换CPU>相关知识.本篇中小编将再为您讲解标题Java如何在内存有限的情况下实现一个超大数组?jvm性能调优+内存模型 ...

最新文章

  1. python处理excel表格实例-python2 对excel表格操作完整示例
  2. 计算机主机安装系统安装系统,系统重装
  3. java多个条件排序_java定制化排序,多个条件排序
  4. 处理quartz 异常 Couldn‘t retrieve trigger: No record found for selection of Trigger with key:
  5. 【POJ1328】Radar Installation(贪心,决策包容)
  6. SQL查询语句精华 笔记
  7. 19-background
  8. devexpress TreeList递归及点击获取数据
  9. 浅谈EM算法的两个理解角度
  10. RDMA 、InfiniBand、IB卡、IB驱动 之间的关系!
  11. 老男孩Day9作业:高级FTP
  12. 电脑哪个服务器可以玩无限连击,无尽之剑3手把手教你无限连击攻略
  13. Elasticsearch 7.X 中文分词器 ik 使用,及词库的动态扩展
  14. 月薪 800 到 2w 加
  15. 智慧城市与智能网联汽车如何协同发展?
  16. 沈阳大学计算机李华,计算机自适应考试曝光率控制-数学专业毕业论文.pdf
  17. ctfshow菜鸡杯 部分wp
  18. 一周内“克隆”了 Twitter,没用一行代码
  19. 【锐捷交换】接入交换机安全配置
  20. 一入魔兽深似海,回首已是中年人

热门文章

  1. vscode在windows端远程连接ubuntu工作站
  2. 用 Java 生成和识别二维码就这么简单
  3. 全景视频拼接算法参考资料
  4. python期末考试重点_Python期末复习笔记
  5. 冒泡排序原理以及算法
  6. 移动端对比后端逐渐“式微”?在互联网大环境下如何避免久当生锈的”螺丝钉”去成为一个优秀的Android开发者?
  7. 本科生如何学习科研方法论
  8. 为什么需要射频校准?
  9. 用 nanodet 训练口罩检测模型,并在 jetson nano 下部署测试
  10. 【拓展】编程语言中的“前浪”和“后浪”