文档章节

深入理解 Java 虚拟机

编走编想
 编走编想
发布于 2015/11/02 12:20
字数 1189
阅读 141
收藏 4
JVM

2015年11月19日更新

封面

3. 垃圾收集器和内存回收策略

3.5 垃圾收集器

垃圾收集算法,除了G1,目前都可分为新生代和老生代算法。这些算法有两个性能侧重点:1. 回收停顿时间;2. 吞吐量。偏向前者的有 CMS 和 G1,CMS 是老生代回收算法。常与 CMS 搭配使用的是 ParNew 算法。偏重吞吐量的算法是 Parellel Scavenge。这是个新生代算法,常与之搭配的老生代算法是 Parellel Old。

对于大型网站这样的需要实时响应用户请求的应用,常用的垃圾收集器是 ParNew + CMS。其实这个组合还包括了 Serial Old 收集器。因为 CMS 是一个允许边分配边回收的,所以在 CMS 收集垃圾的同时,用户线程还会产生新的垃圾。如果预留的内存空间无法满足新产生的内存垃圾的使用,便会触发“Concurrent Mode Failure”,这时便会使用 Serial Old 收集器回收内存。

对于 Hadoop 这样离线批处理任务应用,Parelle Scavenge 是合适的选择。

G1 收集器的目标是最终能取代 CMS。改进点在于减少内存碎片和降低 GC 停顿时间。G1 只在逻辑上区分新生代和老生代。在物理上,G1 将内存分成一个个独立区域,这些独立区域会组合成新生代和老生代。现在 G1 还缺乏实际运行的考验,但是 Oracle 在不断改进,相信今后 G1 会被使用的越来越多。

附:关于 Major GC

我们有时会在关于 JVM 垃圾回收的文章里看到 Major GC 这个叫法,但在官方文档中并没有 Major GC 的定义,只有 Full GC,

3.6 内存分配与回收策略

JVM 优先将对象分配到 Eden 空间中。默认配置下,Eden 空间与两个 Survivor 空间大小的比是 8:1:1。Young Gen 的垃圾回收被称为 Minor GC,Old Gen 的垃圾回收包括 Major GC 和 Full GC。虽然对象是优先分配到 Eden 空间,但是对于大于一定值的连续字符串或数组这样的大对象,是被直接分配在 Old Gen 中,目的是避免大对象在 Young Gen 中被反复拷贝。

JVM 堆中长期存活的对象将进入 Old Gen。所谓长期存活是指年龄大于一定值,默认是 15。对象每在一次 GC 中存活,年龄便会增加 1。这是 JVM 的静态对象年龄判断机制,还有一个动态机制。

从 JDK6 u24 开始,空间分配担保策略变得简单了。

4. 虚拟机性能监控和故障处理工具

4.2 JDK 的命令行工具

  • jstat 用来统计 gc 的相关信息:各代空间大小、比例、gc 时间等。示例:jstat -gc <pid> <interval> <count> 输出:
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT  
38400.0 38400.0 5280.8  0.0   307200.0 143769.7  947200.0   304919.5  133132.0 126626.8 16472.0 15388.6    188   19.617  40     26.275   45.892

其中 MCMU 是只有 Java 8 才有的,表示 Metaspace 的占用和使用大小。jstat 的一个小问题的地方是显式不对齐。

7. 虚拟机类加载机制

7.4 类加载器

JVM 中的类加载器主要分两种,一种是启动加载器(Bootstrap ClassLoader),它是用 C++ 写成,用于加载 rt.jar 中的类(JDK 中的类);另一个是应用程序类加载器(Applcation ClassLoader),用于加载用户程序的 ClassPath 上的类。这是开发人员常接触到的类加载器,也是应用程序默认的类加载器。通过 ClassLoader.getSystemClassLoader() 获得的类加载器就是这个。

在 JVM 中,同一个类的前提是这个类必须是同一个类加载器所加载,否则即便是同一个类文件,JVM 也可能不认为其是同一个类。

Java 的类加载器之间有层次关系,即每个类加载器都有一个父加载器。这个父加载器可通过 ClassLoader.getParent() 方法得到,通过构造函数设置。

JVM 使用的,也是推荐的类加载器模型是双亲委派模型。其大意是,当一个类加载器尝试加载一个类的时候,其首先会将类加载动作委派给父加载器执行。只有当父加载器无法完成这个类加载动作时,这个类加载器才会尝试自己去加载类。这个模型使得像 java.lang.Object 这样的类,不论是用哪个用户级的类加载器,其加载到的都是同一个,从而不会发生混乱。

© 著作权归作者所有

共有 人打赏支持
编走编想
粉丝 150
博文 128
码字总数 111395
作品 0
海淀
程序员
私信 提问
面试中关于Java虚拟机(jvm)的问题看这篇就够了

最近看书的过程中整理了一些面试题,面试题以及答案都在我的文章中有所提到,希望你能在以问题为导向的过程中掌握虚拟机的核心知识。面试毕竟是面试,核心知识我们还是要掌握的,加油~~~ 下面...

snailclimb
2018/05/12
0
0
JVM系列开篇:为什么要学虚拟机?

跟许多人一样,我一开始接触 Java 虚拟机只是因为面试需要用到,所以硬着头皮看看。所以很多人对于为什么要学虚拟机这个问题,他们的答案都是:因为面试。但我经过了几年的学习和实战,我发现...

陈树义
2018/11/06
0
0
分享面试中Java虚拟机的知识

投Java岗的同学难免会被问到Java虚拟机,如果能答出来一定加分不少。 前一段时间读了《深入理解Java虚拟机》,读完之后有种豁然开朗的感觉。发现自己以前写的Java程序都太Low了,在不了解Jav...

350142639
2016/08/31
354
1
《成神之路-基础篇》JVM——JVM内存结构(已完结)

Java内存模型,Java内存管理,Java堆和栈,垃圾回收 本文是《成神之路系列文章》的第一篇,主要是关于JVM的一些介绍。 持续更新中 参考文章: Java虚拟机的内存组成以及堆内存介绍 Java堆和栈...

2018/05/05
0
0
读《深入理解Java虚拟机》- 笔记08

《深入理解Java虚拟机:JVM高级特性与最佳实践》第2版 第10章 早期(编译期)优化 59. 语法糖 在计算机语言中添加某种语法,对语言的功能没有影响,但是方便开发人员使用。 泛型是一种语法糖...

阿历Ali
2018/08/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

html5代码书写规范

DOCTYPE 页面文档类型统一使用HTML5 DOCTYPE. <!DOCTYPE html> Meta字符集设置 声明方法遵循HTML5的规范, Meta文件使用 "UTF-8" 浏览器显示编码指定. <meta charset="utf-8"> 手机端页面添......

niuhongxia
27分钟前
3
0
怎么修改 phpstorm 中注释的开始位置

PHPStorm 版本:v2018.3 如下图设置:

whoru
36分钟前
2
0
Android Arcface人脸识别sdk使用工具类

public class FaceUtil{ private static final String TAG = FaceUtil.class.getSimpleName(); private static FaceUtil faceInstance = null; public FaceDB mFaceDB; pri......

是哇兴哥棒棒哒
44分钟前
2
0
JFreeChart中文API和树形详解

-------------------------------- JfreeChart 中文API -------------------------------- 要想绘制出漂亮的图表,就必须了解图表的构成部分,将图表进行分解成N个部分。 然后再对每一个部分...

喜欢搬砖的农民工
45分钟前
2
0
Android ViewPager

1.PagerAdapter { public int getCount() { return list.size(); } public Object instantiateItem(ViewGroup container, int postion) { container.addView(iv); return iv; } public void ......

Coding缘
47分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部