[转帖]详解JVM内存布局及GC原理,值得收藏
概述
https://www.toutiao.com/i6731345429574713868/
java发展历史上出现过很多垃圾回收器,各有各的适应场景,不仅仅是开发,作为运维也需要对这方面有一定的掌握,今天简单介绍一下java的内存布局以及各种垃圾回收器的原理。
JVM内存布局
JVM从概念上大致分为6个(逻辑)区域:
这6块区域按是否被线程共享,可以分为两大类:
一类是每个线程所独享的:
1)PC Register:也称为程序计数器, 记录每个线程当前执行的指令信。eg:当前执行到哪一条指令,下一条该取哪条指令。2)JVM Stack:也称为虚拟机栈,记录每个栈帧(Frame)中的局部变量、方法返回地址等。3)Native Method Stack:本地(原生)方法栈,顾名思义就是调用操作系统原生本地方法时,所需要的内存区域。
上述3类区域,生命周期与Thread相同,即:线程创建时,相应的区域分配内存,线程销毁时,释放相应内存。
另一类是所有线程共享的:
1)Heap:即鼎鼎大名的堆内存区,也是GC垃圾回收的主站场,用于存放类的实例对象及Arrays实例等。2)Method Area:方法区,主要存放类结构、类成员定义,static静态成员等。3)Runtime Constant Pool:运行时常量池,比如:字符串,int -128~127范围的值等,它是Method Area中的一部分。
Heap、Method Area 都是在虚拟机启动时创建,虚拟机退出时释放。
总之,程序运行时,内存中的信息大致分为两类,一是跟程序执行逻辑相关的指令数据,这类数据通常不大,而且生命周期短;一是跟对象实例相关的数据,这类数据可能会很大,而且可以被多个线程长时间内反复共用,比如字符串常量、缓存对象这类。
将这两类特点不同的数据分开管理,体现了软件设计上“模块隔离”的思想。好比我们通常会把后端service与前端website解耦类似,也更便于内存管理。
GC垃圾回收原理
1、哪些内存区域需要GC ?
thread独享的区域:PC Regiester、JVM Stack、Native Method Stack,其生命周期都与线程相同(即:与线程共生死),所以无需GC。线程共享的Heap区、Method Area则是GC关注的重点对象。
2、常用的GC算法
1)mark-sweep 标记清除法
如上图,黑色区域表示待清理的垃圾对象,标记出来后直接清空。该方法简单快速,但是缺点也很明显,会产生很多内存碎片。
2)mark-copy 标记复制法
思路也很简单,将内存对半分,总是保留一块空着(上图中的右侧),将左侧存活的对象(浅灰色区域)复制到右侧,然后左侧全部清空。避免了内存碎片问题,但是内存浪费很严重,相当于只能使用50%的内存。
3)mark-compact 标记-整理(也称标记-压缩)法
避免了上述两种算法的缺点,将垃圾对象清理掉后,同时将剩下的存活对象进行整理挪动(类似于windows的磁盘碎片整理),保证它们占用的空间连续,这样就避免了内存碎片问题,但是整理过程也会降低GC的效率。
4)generation-collect 分代收集算法
上述三种算法,每种都有各自的优缺点,都不完美。在现代JVM中,往往是综合使用的,经过大量实际分析,发现内存中的对象,大致可以分为两类:有些生命周期很短,比如一些局部变量/临时对象,而另一些则会存活很久,典型的比如websocket长连接中的connection对象,如下图:
纵向y轴可以理解分配内存的字节数,横向x轴理解为随着时间流逝(伴随着GC),可以发现大部分对象其实相当短命,很少有对象能在GC后活下来。因此诞生了分代的思想,以Hotspot为例(JDK 7):
将内存分成了三大块:年青代(Young Genaration),老年代(Old Generation),永久代(Permanent Generation),其中Young Genaration更是又细为分eden,S0,S1三个区。
结合我们经常使用的一些jvm调优参数后,一些参数能影响的各区域内存大小值,示意图如下:
GC主要过程
下图引自阿里出品的《码出高效-Java开发手册》一书,梳理了GC的主要过程。
后面会分享更多devops和DBA方面内容,感兴趣的朋友可以关注下!
[转帖]详解JVM内存布局及GC原理,值得收藏的更多相关文章
- JVM内存布局及GC知识回顾
注:本文篇幅较长,且需要有一定的java基础,建议各位看官,备好瓜子.饮料.小板凳,摆个让自己舒服的姿势,慢慢细看^_^, 文中所有素材,均来自互联网,本人只是详细梳理了一遍,形成此文. 一.JVM运 ...
- JVM内存布局及GC知识
一.JVM运行时内存布局 按java 8虚拟机规范的原始表达:(jvm)Run-Time Data Areas, 暂时翻译为"jvm运行时内存布局". 从概念上大致分为6个(逻辑) ...
- Java虚拟机详解----JVM内存结构
http://www.cnblogs.com/smyhvae/p/4748392.htm 主要内容如下: JVM启动流程 JVM基本结构 内存模型 编译和解释运行的概念 一.JVM启动流程: JVM启 ...
- 直通BAT必考题系列:深入详解JVM内存模型与JVM参数详细配置
VM基本是BAT面试必考的内容,今天我们先从JVM内存模型开启详解整个JVM系列,希望看完整个系列后,可以轻松通过BAT关于JVM的考核. BAT必考JVM系列专题 1.JVM内存模型 2.JVM垃圾 ...
- 深入详解JVM内存模型与JVM参数详细配置
对于大多数应用来说,Java 堆(Java Heap)是Java 虚拟机所管理的内存中最大的一块.Java 堆是被所有线程共享的一块内存区域,在虚拟机启动时创建. JVM内存结构 由上图可以清楚的看到 ...
- 深入详解JVM内存模型
JVM内存结构 由上图可以清楚的看到JVM的内存空间分为3大部分: 堆内存 方法区 栈内存 其中栈内存可以再细分为java虚拟机栈和本地方法栈,堆内存可以划分为新生代和老年代,新生代中还可以再次划分为 ...
- BAT面试必问题系列:深入详解JVM 内存区域及内存溢出分析
前言 在JVM的管控下,Java程序员不再需要管理内存的分配与释放,这和在C和C++的世界是完全不一样的.所以,在JVM的帮助下,Java程序员很少会关注内存泄露和内存溢出的问题.但是,一旦JVM发生 ...
- 详解JVM内存模型与JVM参数详细配置
对于大多数应用来说,Java 堆(Java Heap)是Java 虚拟机所管理的内存中最大的一块.Java 堆是被所有线程共享的一块内存区域,在虚拟机启动时创建. JVM内存结构 由上图可以清楚的看到 ...
- Java虚拟机详解----JVM常见问题总结
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
随机推荐
- 快速上手mpvue 项目
初始化一个 mpvue 项目 $ node -v v8.9.0 $ npm -v 5.6.0 # 2. 由于众所周知的原因,可以考虑切换源为 taobao 源 $ npm set registry h ...
- 20191214数组习题之三:报数(附pow函数简单用法)
- BZOJ3781小B的询问
莫队裸题. 维护的时候有的打法是利用(a-1)^2==a^2-2*a+1转移,也可以,但是通用性不太够. 下面的打法就是先把这个点的贡献删掉,然后更新这个点,再把这个点的贡献加回来,这种解法更加通用一 ...
- LeetCode 222. 完全二叉树的节点个数(Count Complete Tree Nodes)
题目描述 给出一个完全二叉树,求出该树的节点个数. 说明: 完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位 ...
- 解决跨操作系统平台JSON中文乱码问题
解决跨操作系统平台JSON中文乱码问题 LINUX统一使用utf-8编码,WINDOWS却不是. LINUX中间件,传输JSON给WINDOWS程序,会乱码. 解决办法: 对JSON字段是字符串类型的 ...
- Team团队管理执行力
执行力是什么_百度知道https://zhidao.baidu.com/question/144991863.html [图文]如何提高团队执行力 - 百度文库https://wenku.baidu. ...
- Docs-.NET-C#-指南-语言参考-预处理器指令:#elif(C# 参考)
ylbtech-Docs-.NET-C#-指南-语言参考-预处理器指令:#elif(C# 参考) 1.返回顶部 1. #elif(C# 参考) 2015/07/20 #elif 可以创建复合条件指令. ...
- web前端之es6对象的扩展
1.属性的简洁表示法 2.属性名表达式 表达式作为对象的属性名 3.方法的 name 属性 例如:函数的name 属性,返回函数名. 4.Object.is() ES 比较两个值是否相等,只有两个运算 ...
- 常用sql2
mysql中的NULL的判断 mysql> delete from `zhangchao` where x='NULL'; Query OK, 0 rows affected (0.00 ...
- python使用redis实现协同控制的分布式锁
python使用redis实现协同控制的分布式锁 上午的时候,有个腾讯的朋友问我,关于用zookeeper分布式锁的设计,他的需求其实很简单,就是节点之间的协同合作. 我以前用redis写过一个网络锁 ...