jvm虚拟内存分布 与 GC算法
jvm虚拟内存分布
程序计数器(PC寄存器)(线程私有):
每个线程启动的时候,都会创建一个PC(Program Counter,程序计数器)寄存器。
PC寄存器的内容总是指向下一条将被执行指令的地址,这里的地址可以是一个本地指针,
也可以是在方法区中相对应于该方法起始指令的偏移量。
本地方法栈(线程私有):
jvm调用操作系统native方法所使用的栈。
虚拟机栈(线程私有):
栈帧(栈的单位):每个方法执行,都会创建一个栈帧,保存到栈的顶部,方法执行完毕后出栈。
栈帧用于存储局部变量表,操作数栈,动态链接,方法出口
局部变量表:存放编译器可知的各种基本数据类型,引用类型的引用,返回地址等。
Java栈的区域很小,特点是存取速度很快,
所以在stack中存放的都是快速执行的任务,基本数据类型的数据,和对象的引用(reference)
每个线程包含一个栈区,栈分为3个部分:基本数据类型的变量区、执行环境上下文、操作指令区(存放操作指令)。
方法区(静态区)(所有线程共享):
存储加载的:①类(class),②静态变量(static变量),③静态方法,④常量,⑤成员方法
类信息包含类的版本、字段、方法、接口等信息
运行时常量池(包含了类的运行时常量和静态方法等Class常量池的数据)
虚拟机堆(所有线程共享):
唯一目的就是存放对象实例(与引用是两个概念),也是垃圾回收器主要管理的地方,故又称GC堆。
JVM堆内存的划分
在JDK7以及其前期的JDK版本号中:
堆内存通常被分为三块区域:新生代内存(young generation)、老生代(old generation)、永生代(Permanent Generation for VM Matedata)
Java8:
把存放元数据中的永生代内存从堆内存中移到了叫做“Metaspace”的本地内存(Native memory)。
Permanent:
即持久代(Permanent Generation):
主要存放的是Java类定义信息,与垃圾收集器要收集的Java对象关系不大。
持久代对垃圾回收没有显著影响。
但是有些应用可能动态生成或调用一些Class,例如Hibernate CGLib等。
在这种时候往往需要设置一个比较大的持久代空间来存放这些运行过程中动态增加的类型。
Heap = Old + NEW = Eden, from, to
Old 即 年老代(Old Generation)
New 即 年轻代(Young Generation)。
堆的大小可通过参数 -Xms(堆的初始容量)、-Xmx(堆的最大容量) 来指定
默认的,Edem : from : to = 8 : 1 : 1 (可以通过参数 -XX:SurvivorRatio 来设定)。
年轻代:
所有新生成的对象首先都是放在年轻代。
年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。
年轻代一般分3个区,Eden区,Survivor区(from和to)。
JVM 每次只会使用 Eden 和其中的一块 Survivor 区域来为对象服务,所以无论什么时候,总是有一块 Survivor 区域是空闲着的。
针对年轻代的垃圾回收即Young GC。
年老代:
在年轻代中经历了N次(可配置)垃圾回收后仍然存活的对象,就会被复制到年老代中。
因此,可以认为年老代中存放的都是一些生命周期较长的对象。
针对年老代的垃圾回收即Full GC。
Young GC回收过程(复制算法)
Eden –> Survivor Space 以及 From Survivor Space 与 To Survivor Space 之间实行 Copying 算法。
1,当Eden区满的时候,会触发第一次young gc,把还活着的对象拷贝到Survivor From区。
Survivor From区放不下,就将剩下的对象放老年代。
2,当再次触发young gc的时候,会扫描Eden区和From区域,对两个区域进行垃圾回收。
经过这次回收后还存活的对象,则直接复制到To区域,并将Eden和From区域清空。
如果一次回收中,Survivor+Eden中存活下来的内存超过了10%,则需要将一部分对象分配到老年代
3,当后续Eden又发生young gc的时候,会对Eden和To区域进行垃圾回收,存活的对象复制到From区域,并将Eden和To区域清空。
4,部分对象会在From和To区域中复制来复制去,如此交换15次
(默认是15次,表示最大值,但不一定15此,可以通过参数 -XX:MaxTenuringThreshold 来设定),
最终如果还是存活,就存入到老年代。
但这也不是一定的,对于一些较大的对象 ( 即需要分配一块较大的连续内存空间 ) ,则是直接进入到老年代。
优点:不会产生内存碎片,效率高。
缺点:需要双倍空间。
Full GC(标记-清除算法)
1. 标记:
从引用根节点开始扫描,标记所有被引用的对象
2. 清除
扫描整个堆内存空间,回收未被标记的对象。
优点:不需要额外空间
缺点:
两次扫描,耗时严重;产生内存碎片。
以后需要为较大的对象分配内存空间时,若无法找到足够的连续的内存空间,就会提前触发一次 GC 的收集动作。
特点:
Full GC 发生的次数不会有 Minor GC 那么频繁,并且做一次 Full GC 要比进行一次 Minor GC 的时间更长,一般是 Minor GC 的 10倍以上。
标记整理算法(Mark-Compact):
在原有的标记-清除算法的基础上,提出了优化方案。
标记到的可用对象整体向一侧移动,然后直接清除掉可用对象边界以外的内存。
这样既解决了内存碎片的问题。又不需要原有的空间换时间的硬件浪费。
标记整理算法的缺点:
标记整理算法由于需要不断的移动对象到另外一侧,而这种不断的移动其实是非常不适合杂而多的小内存对象的。
每次的移动和计算都是非常复杂的过程。
因此在使用场景上,就注定限制了标记整理算法的使用不太适合频繁创建和回收对象的内存中。
jvm虚拟内存分布 与 GC算法的更多相关文章
- jvm系列(三):java GC算法 垃圾收集器
GC算法 垃圾收集器 概述 垃圾收集 Garbage Collection 通常被称为“GC”,它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了. jvm 中,程序计 ...
- JVM内存模型与GC算法
1.JVM内存模型 JVM内存模型如上图,需要声明一点,这是<Java虚拟机规范(Java SE 7版)>规定的内容,实际区域由各JVM自己实现,所以可能略有不同.以下对各区域进行简短说明 ...
- JVM培训之一些GC算法的理论知识
很精彩的一次内部分享,介绍了大部分的GC算法理论知识,JVM博大精深,本篇文章只是结合本次内部分享总结的一些理论知识,如果有大佬有疑问,欢迎留言指出! Concurrent:并发,程序一边运行一边做G ...
- JVM内存管理之GC算法精解(五分钟教你终极算法---分代搜集算法)
引言 何为终极算法? 其实就是现在的JVM采用的算法,并非真正的终极.说不定若干年以后,还会有新的终极算法,而且几乎是一定会有,因为LZ相信高人们的能力. 那么分代搜集算法是怎么处理GC的呢? 对象分 ...
- JVM内存管理之GC算法精解(复制算法与标记/整理算法)
本次LZ和各位分享GC最后两种算法,复制算法以及标记/整理算法.上一章在讲解标记/清除算法时已经提到过,这两种算法都是在此基础上演化而来的,究竟这两种算法优化了之前标记/清除算法的哪些问题呢? 复制算 ...
- JVM内存管理之GC算法精解(五分钟让你彻底明白标记/清除算法)
相信不少猿友看到标题就认为LZ是标题党了,不过既然您已经被LZ忽悠进来了,那就好好的享受一顿算法大餐吧.不过LZ丑话说前面哦,这篇文章应该能让各位彻底理解标记/清除算法,不过倘若各位猿友不能在五分钟内 ...
- JVM内存模型与GC算法(简介)
JVM内存模型如上图,需要声明一点,这是<Java虚拟机规范(Java SE 7版)>规定的内容,实际区域由各JVM自己实现,所以可能略有不同.以下对各区域进行简短说明. 1.1程序计数器 ...
- JVM的四种GC算法
程序在运行过程中,会产生大量的内存垃圾(一些没有引用指向的内存对象都属于内存垃圾,因为这些对象已经无法访问,程序用不了它们了,对程序而言它们已经死亡),为了确保程序运行时的性能,java虚拟机在程序运 ...
- JVM虚拟机垃圾回收(GC)算法及优缺点
一.什么是GC GC是jvm的垃圾回收,垃圾回收的规律和原则为: 次数上频繁收集新生区(Young) 次数上较少收集养老区(Old) 基本上不动永久区(Perm) 二.GC算法(分代收 ...
随机推荐
- python列表中enumerate和zip函数用法
enumerate: 定义:enumerate() 函数用于将一个可遍历的数据对象(如列表.元组或字符串)组合为一个索引序列,同时列出数据和数据下标 例子: list1 =[89,98,00,75,6 ...
- 提供免费可商用的优秀背景视频素材——COVERR
现在经常看到很多网站都是贴近更现代化的设计,首页都会放置跟网站内容相关的视频短片作为背景,不用按下播放按钮,就有动态显示效果,跟以往静态图片相较下更动态.更有活力,对网站的视觉体验有一定的提升作用.但 ...
- 伪类checked
困惑了好久的复选框自定义样式终于有了谜底,原来就是一个 :checked 伪类 他的意思就是 匹配任意被勾选/选中的radio(单选按钮),chexked(复选框),或者option(select项) ...
- cpu相关信息查看
查看CPU型号:grep "model name" /proc/cpuinfo | uniqdmidecode -s processor-version | uniq 查看物理CP ...
- nginx防DDOS、cc、爬虫攻击
一.防止DDOS.CC攻击 http { limit_conn_zone $binary_remote_addr zone=perip:10m; limit_conn_zone $server_nam ...
- H5在js中向指定的元素添加样式
今天在做一个按钮的功能控制,点击之后,要根据判断条件,修改按钮的样式,然后就发现了一个巨好用的方法, <button type="button" id="btn_A ...
- k8s 命令
Kubernetes 常用安装和使用命令总结 获取所有命名空间上的pod kubectl get pod -o wide --all-namespaces 查看pod IP时使用 kubectl ge ...
- Algo: Binary search
二分查找的基本写法: #include <vector> #include <iostream> int binarySearch(std::vector<int> ...
- [翻译]windows下 连接到 bitnami的phpmyadmin
bitnami 因为安全考虑,只能 localhost 访问 phpmyadmin 为了能通过SSH 隧道访问 phpMyAdmin,你需要一个ssh 客户端.参考文章介绍使用中选择使用 PuTTY, ...
- re.match与re.search的区别
re.match与re.search的区别 re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None:而re.search匹配整个字符串,直到找到一个匹配. 实 ...