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算法(分代收 ...
随机推荐
- 32-Ubuntu-用户权限-03-修改文件权限
chmod 简介 chmod可以修改用户或组对文件或目录的权限. 命令格式如下: chmod +/-rwx 文件名/目录名 修改文件权限 例:demo.txt 1.增加权限 例:增加demo.txt的 ...
- VisualStuido中将C#脚本封装打包DLL并调用
DLL (Dynamic Link Library)---动态链接库 首先了解下使用DLL的优势,程序运行时不用加载所有代码,只有运行到引用时,才从DLL库中取出.并且使用DLL文件还可以减小程序体积 ...
- Java支持的数据类型有哪些?什么是拆装箱?
Java中有八种基本数据类型以及引用类型 基本数据类型: byte(1字节),short(2字节),int(4字节),long(8字节),char(2字节),boolean(不确定,取值是true/f ...
- keras 或 tensorflow 调用GPU报错:Blas GEMM launch failed
GPU版的tensorflow在模型训练时遇到Blas GEMM launch failed错误,或者keras遇到相同错误(keras 一般将tensorflow作为backend,如果安装了GPU ...
- 从零开始搭建系统1.2——Nginx安装及配置
一.安装准备 首先由于nginx的一些模块依赖一些lib库,所以在安装nginx之前,必须先安装这些lib库,这些依赖库主要有g++.gcc.openssl-devel.pcre-devel和zlib ...
- 两台linux服务器传文件方法
scp -r /当前服务器的文件的路径 第二台服务器的用户名@第二台服务器的ip:/第二台服务器的存放文件的路径
- P2290 [HNOI2004]树的计数
P2290 [HNOI2004]树的计数prufer序列模板题 #include <iostream> #include <cstdio> #include <queue ...
- delphi RichView的使用介绍
RichView 组件 由 9 个组件模块组成,分别是: 1.TRVStyle:主要是定义RICHVIEW样式,定义后,其它RIHCVIEW都可以引用此样式. 2.TRichView :主要用于显示 ...
- thinkphp 标签扩展
标签库加载直线电机参数 模板中加载标签库,预加载自定义标签库,扩展内置标签库的加载 请参考:http://document.thinkphp.cn/manual_3_2.html#taglib 自定义 ...
- bzoj1012题解
[解题思路] 强制在线线段树/树状数组,没什么好说的..复杂度O(mlog2m)(线段树)或O(mlog22m)(树状数组). [参考代码] (还naive的时候写的zkw真是翔..) #includ ...