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算法(分代收 ...
随机推荐
- STL 队列模板实现
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u010016150/article/details/32715801 C++ Prime确实有点 ...
- C static extern和全局变量
#include <stdio.h> //默认全局变量为外部变量 int a; //当全局变量前面加上static时,该变量为内部变量 static int b; void test(); ...
- 微信小程序开发简易计算器改进版
微信小程序开发计算器有多种方法,但是大部分代码比较复杂.不容易理解.本案例进行了改进,主要是组件bindtap属性绑定的自定义函数clickBtn(),采用了switch语句,使得代码结构更加清晰,学 ...
- PL/SQL Developer 查看查询的执行计划
https://zhuanlan.zhihu.com/p/65771352 通过 PL/SQL Developer 查看查询的执行计划 1 什么是执行计划 执行计划是一条查询语句在 Oracle 中的 ...
- DataTable转对象Model
我们经常需要从数据库表中取数,取数是以取DataTable的方式,但是我么希望以对象为单位进行这种操作.即存在把取到的DataTable(数据表)转换为ModelList(对象集合)的需求. 原理稍微 ...
- js 购物车的数量加减,对应的总价也随机变化
html相关的源码: <div class="goods_num clearfix"> <div class="num_name fl"> ...
- 使用Sonatype Nexus搭建Maven私服后,如何添加第三方JAR包
使用Sonatype Nexus搭建Maven私服后如何添加第三方JAR包 步骤如下 1.打开nexus地址,进行登录 2.登录Nexus后,点击右侧的“Repositories”,显示当前Nexus ...
- csp-s模拟测试96
csp-s模拟测试96 $T1$一眼慢速乘,$T2$稍证一手最优性尝试用神奇数据结构优化,无果,弃.$T3$暴力+信仰. 100 03:16:38 95 03:16:56 35 03:17:10 23 ...
- c++ 枚举简单举例
#include <iostream> enum Enumeration{ VAL1, VAL2, VAL3=100, VAL4 }; int main() { using namespa ...
- class12_pack_grid_place 放置位置
其中的部分运行效果图(程序见序号1): #!/usr/bin/env python# -*- coding:utf-8 -*-# ----------------------------------- ...