整体架构

Jvm = 类加载器 + 执行引擎 + 运行时数据区域

类加载器

● 作用

类加载器是将编译好的class文件加载到内存中,并进行验证、初始化等步骤,形成能被jvm直接使用的类型。

● 加载过程

可分解为5个步骤:加载–>连接–>初始化 –> 使用 –> 卸载。

  • 加载:把class文件以二进制字节流的形式存储到方法区中,并在堆中创建对应的class对象。
  • 连接:连接过程又分为3步,验证、准备、解析。

① 验证:验证文件格式、元数据、字节码是否符合规范。

② 准备:为成员变量分配内存并初始化值。

③ 解析: 解析是虚拟机将常量池的符号引用替换为直接引用的过程。

  • 初始化:初始化过程主要包括执行构造方法,初始化静态变量、静态块。

执行引擎

其作用是将class字节码转变成机器能识别的码,然后在jvm中创建方法栈去执行方法。

运行时数据区

运行时数据区包含方法区、堆、虚拟机栈、本地方法栈、程序计数器 。如下图:

● 方法区

方 法区同堆一样,是所有线程共享的内存区域,为了区分堆,又被称为非堆。 用于存储已被虚拟机加载的类信息、常量、静态变量,如static修饰的变量加载类的时候就被加载到方法区 中。

● 堆

简单的说就是对象的存储区,它是被所有线程共享的一块区域 堆是java虚拟机管理内存最大的一块内存区域,因为堆存放的对象是线程共享的,所以多线程的时候也需要同步机制。堆回收算法使用的复制算法效率高没有碎片利用率低分为三个区 eden 、 S0、 S1 按照8:1:1的默认值。

● 程序计数器

我们知道对于一个处理器,在一个确定的时刻都会执行一条线程中的指令,一条线程中有多个指令,为了线程切换可以恢复到正确执行位置,每个线程都需有独 立的一个程序计数器,不同线程之间的程序计数器互不影响,独立存储。

● 虚拟机 栈

虚拟机栈指的是java方 法执行的内存概念模型,每个方法执行时都会在栈内存里面创建一个栈帧,栈帧用来存储局 部变量表、操作数栈、动态链接、方法出口等信息。 每个方法从调用到执行完成,都会对应一个栈帧在虚拟机中入栈到出栈的过程。

● 本地方法栈

本地方法栈与虚拟机栈功能相似,是为虚拟机使用的Native方法服务。有的虚拟机可能会把这两个栈合二为一。

● 程序计数器

我们知道对于一个处理器,在一个确定的时刻都会执行一条线程中的指令,一条线程中有多个指令,为了线程切换可以恢复到正确执行位置,每个线程都需有独 立的一个程序计数器,不同线程之间的程序计数器互不影响,独立存储。

目前比较常用的gc回收是年代回收法,JVM将堆分成了二个大区新生代 、老年代 和持久代。新生代和老年代的内存区域是在堆上也是gc回收的主要区域,默认情况新生代与老年代比例为1:2,该值可以通过参数–XX:NewRatio 设定。 持久代是在方法区,持久代存放一些一般不需要被回收的对象,持久代一般情况不会触发GC。

● 新生代

新生代又分为Eden和Survivor区,而Survivor由S0 和 S1 组成。,新生代默认分配是 eden:S0:S1为8:1:1, 该值可以通过参数 –XX:SurvivorRatio 来设定。 新生代采用的是复制回收算法,当第一次产生对象是在eden区分配空间,当eden区空间满了时候,会在S0区域分配空间,当S0空间满了时候会触发Minor GC , 这时候会把eden区和S0区存活对象复制出来放在S1区,然后直接清空eden区和S0区,新生代就是这么反复的进行垃圾回收。

● 老年代

老年代用于存放经过多次Minor GC之后依然存活的对象 ,在年代回收法对象有个年龄的概念,在新生代每进行一次 Minor GC仍然存活的对象年龄都会加1,当对象年龄达到一定的值就会进入老年代区域, 默认的值是15 ,可以通过参数-XX:MaxTenuringThreshold 来设定 。 还有一种情况是当对象特别大时候不需要达到设定值会直接进入老年代。老年代由于对象比较稳定所以老年代采用标记整理算法进行Full GC,此算法会减少内存碎片带来的效率损耗,下面会重点介绍一下本算法。

● 垃圾收集算法

①. (标记-清除)算法

这是最基础的算法,标记-清除算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,标记完成后统一回收所有被标记的对象。 这种算法的缺点是会产生内存碎片而且效率也不高。下图是此算法的执行过程。

②. (复制)算法

为了解决 (标记-清除) 算法的缺陷,复制算法就被提了出来。它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,这种算法虽然实现简单,运行高效且不容易产生内存碎片,但是却对内存空间的使用做出了高昂的代价,因为能够使用的内存缩减到原来的一半。很显然,复制算法的效率跟存活对象的数目多少有很大的关系,如果存活对象很多,那么复制 算法的效率将会大大降低。我们的新生代GC算法采用的是这种算法 。复制算法执行过程如下图:

③. (标记-整理)算法

因为复制算法效率低,清除算法会产生内存碎片,所以又产生了 了(标记-整理)算法。该算法标记阶段和(标记-清除) 一样,但是在完成标记之后,它不是直接清理可回收对象,而是将存活对象都向一端移动,然后回收被标记的对象,此算法的好处是效率高,同时不会产生内存碎片。 标记-整理 算法执行过程如下图:

● 内存泄漏

在我们平时写代码时候很容易发生gc没有及时回收的情况,这时就会发生内存泄漏情况,下面介绍一个内存泄漏的例子。

Public class test{Public static Map map = new HashMap();Public void insert(){for (int i=1;i<100; i++){ Object o=new Object()map.put(i,o);}}}

在这个例子中, 由于map是静态的,所以gc不会回收,当执行insert方法时候,进入for循环,声明o对象,然后放进map里面,执行完此方法o对象原本可以被gc回收,但是由于map是静态的所以不会被回收,这样就会导致内存泄漏,所以我们在写代码时候一定要谨慎使用常量和静态变量这类型的变量,可能在不经意间造成内存泄漏情况。

jvm以及gc都是我们写代码和设计程序时经常能涉及到的知识,深入的学习一下jvm和gc能提高对jvm调优的能力,也可以让自己写出更优雅的代码。提高自己的java水平。

jvm对象从新生代到老年代_深入理解jvm内存模型以及gc原理相关推荐

  1. jvm对象从新生代到老年代_一文搞懂JVM新生代、老年代和永久代

    Java堆是垃圾收集器管理的主要区域,因此很多时候也被称为"GC堆". 从内存回收角度看,由于现在收集器基本都采用分代收集算法,所以Java堆中还可以细分为:新生代和老年代.再细致 ...

  2. jvm对象从新生代到老年代_JVM内存管理、JVM垃圾回收机制、新生代、老年代以及永久代...

    内存模型 JVM运行时数据区由程序计数器.堆.虚拟机栈.本地方法栈.方法区部分组成,结构图如下所示. JVM内存结构由程序计数器.堆.栈.本地方法栈.方法区等部分组成,结构图如下所示: 1)程序计数器 ...

  3. jvm详解 - 新生代与老年代

    *************************************优雅的分割线 ********************************** 分享一波:程序员赚外快-必看的巅峰干货 J ...

  4. java if在内存中_全面理解Java内存模型

    Java 内存模型的抽象 在 java 中,所有实例域.静态域和数组元素存储在堆内存中,堆内存在线程之间共享(本文使用"共享变量"这个术语代指实例域,静态域和数组元素).局部变量( ...

  5. JVM中的新生代和老年代(Eden空间、两个Survior空间)

    现有的主流JVM分别是HotSpot和JRockit,主要研究对象也是这两个.这篇文章里,我们只研究HotSpot,也就是所谓的Sun JVM.目前阶段,Sun的GC方式主要有CMS和G1两种.考虑到 ...

  6. 全面理解java内存模型_深入理解Java内存模型(八)——总结

    处理器内存模型 顺序一致性内存模型是一个理论参考模型,JVM和处理器内存模型在设计时通常会把顺序一致性内存模型作为参照.JVM和处理器内存模型在设计时会对顺序一致性模型做一些放松,因为如果完全按照顺序 ...

  7. JVM中的新生代和老年代

    JVM在程序运行过程当中,会创建大量的对象,这些对象,大部分是短周期的对象,小部分是长周期的对象,对于短周期的对象,需要频繁地进行垃圾回收以保证无用对象尽早被释放掉,对于长周期对象,则不需要频率垃圾回 ...

  8. Java GC、新生代、老年代、gc日志分析

    1.堆内存 Java 中的堆是 JVM 所管理的最大的一块内存空间,主要用于存放各种类的实例对象.  在 Java 中,堆被划分成两个不同的区域:新生代 ( Young ).老年代 ( Old ).新 ...

  9. JVM初探:内存分配、GC原理与垃圾收集器

    JVM内存的分配与回收大致可分为如下4个步骤: 何时分配 -> 怎样分配 -> 何时回收 -> 怎样回收. 除了在概念上可简单认为new时分配外, 我们着重介绍后面的3个步骤: I. ...

最新文章

  1. Python学习小结---粗略列表解析
  2. python制作图形化小游戏_创意编程|Python的GUI简易界面设计测测你的反应力
  3. SharePoint Server 2016 部署安装(三)—— 安装SharePoint Server
  4. 58金融产品经理董宁:互金产品设计21问
  5. 使用google colab运行RNN网络代码报告错误ValueError: Object arrays cannot be loaded when allow_pickle=False
  6. lesson7 集合set
  7. SQL中读取Excel 以及 bpc语言
  8. djano 模型查询
  9. mysql 5.0 修改字符集_修改及查看mysql数据库的字符集
  10. 破解MS Word 的只读密码限制
  11. 【1】windows下IOS开发基础环境搭建
  12. mcal rtm_RTM的完整形式是什么?
  13. AI:人工智能领域具体应用场景案例介绍之以领域划分(CV领域/DS领域/NLP领域/金融领域/爬虫领域)、以项目划分(AI推荐/AI推断/AI法律咨询/AI挖掘)目录来理解技术交互流程
  14. 自学转行前端找到第一份前端工作,做得很吃力,被劝退怎么办?
  15. html 的ul是块矿元素吗,食品化学题库单选判断
  16. Zabbix 如何实现邮件报警通知以及免费短信报警通知
  17. 双球坐标系_2.1 天球坐标系和地球坐标系
  18. 关于维基百科你不知道的十件事:
  19. 搞机吧 | 刷rec、线刷、卡刷教程
  20. Android OpenGL添加光照和材料属性

热门文章

  1. strtok()函数详解
  2. php 返回字符串给aja,解决ajax异步请求返回的是字符串问题
  3. C语言字母和数字数量,请问这个用c怎么做:输入一串字符,分别统计其中数字和字母的个数...
  4. python txt文件读写(追加、覆盖)
  5. 大数据分布式集群搭建(插曲)
  6. 打造自己的树莓派监控系统3--canvas.js绘制数据
  7. java 打开服务器excel文件_Java中上传excel文件并在服务器端读取存入数据库
  8. php中perl配置,配置Apache及运行perl,php
  9. C++_泛型编程与标准库(五)
  10. pandas转mysql特定列_在pandas.DataFrame.to_sql时指定数据库表的列类型