java虚拟机学习笔记

Java技术的核心就是Java虚拟机,因为所有的Java程序都在虚拟机上运行。Java程序的运行需要Java虚拟机、Java API和Java Class文件的配合。Java虚拟机实例负责运行一个Java程序。当启动一个Java程序时,一个虚拟机实例就诞生了。当程序结束,这个虚拟机实例也就消亡。

  java虚拟机结构图如下:

                     


1、Java运行时数据区域

当类加载器将class文件加载到jvm后,Java虚拟机在执行java程序的过程中会把它管理的内存划分为若干个不同的数据区,java虚拟机所管理的内存将会包含以下几个运行时数据区域:

  1. 程序计数器(Program Counter Register)
  2. java虚拟机栈(Java Virtual Macchine Stacks)
  3. 本地方法栈(Native Method Stack)
  4. java堆(Java Heap)
  5. 方法区(Method Area)
  6. 运行时常量池(Runtime Constant Pool)

  1-1、程序计数器:

  程序计数器是一块较小的内存,可以被认作时当前线程所执行的字节码的行号指示器。字节码解释器通过改变计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖计数器实现。每个线程都需要一个独立的计数器,所有程序计数器不是线程共享的。

  当线程执行的是java方法时,计数器记录当前正在执行的虚拟机字节码指令的地址,如果执行的是本地方法,则计数器值为空(Undefined),此内存也是唯一一个在虚拟机规范中没有规定任何OutOfMemoryError情况的区域。  

  1-2、java虚拟机栈:

  该区域也是线程私有的,它的生命周期与线程相同。每个方法在执行时都会创建一个帧栈用于存储局部变量表、操作数栈、动态链接、方法出口信息等,该区域规定了两种异常状况:StackOverflowError和OutOfMemoryError

  每个方法从调用到执行完成的过程都会有一个人对应的帧栈在虚拟机栈中入栈出栈。栈由许多栈帧组成,一个栈帧包含一个Java方法调用的状态。当线程调用一个Java方法时,虚拟机压入一个新的栈帧到该线程的栈中,当该方法返回时,这个栈帧就从栈中弹出。Java栈存储线程中Java方法调用的状态--包括局部变量、参数、返回值以及运算的中间结果等。Java虚拟机没有寄存器,其指令集使用Java栈来存储中间数据。这样设计的原因是为了保持Java虚拟机的指令集尽量紧凑,同时也便于Java虚拟机在只有很少通用寄存器的平台上实现。另外,基于栈的体系结构,也有助于运行时某些虚拟机实现的动态编译器和即时编译器的代码优化。

  1-2-1、局部变量区

  局部变量区被组织为以字长为单位、从0开始计数的数组。字节码指令通过从0开始的索引使用其中的数据。类型为int, float, reference和returnAddress的值在数组中占据一项,而类型为byte, short和char的值在存入数组前都被转换为int值,也占据一项。但类型为long和double的值在数组中却占据连续的两项。

  1-2-2、操作数栈

  和局部变量区一样,操作数栈也是被组织成一个以字长为单位的数组。它通过标准的栈操作访问--压栈和出栈。由于程序计数器无法被程序指令直接访问,Java虚拟机的指令是从操作数栈中取得操作数,所以它的运行方式是基于栈而不是基于寄存器。虚拟机把操作数栈作为它的工作区,因为大多数指令都要从这里弹出数据,执行运算,然后把结果压回操作数栈。

  1-2-3、帧数据区

  除了局部变量区和操作数栈,栈帧还需要帧数据区来支持常量池解析、正常方法返回以及异常派发机制。每当虚拟机要执行某个需要用到常量池数据的指令时,它会通过帧数据区中指向常量池的指针来访问它。除了常量池的解析外,帧数据区还要帮助虚拟机处理Java方法的正常结束或异常中止。如果通过return正常结束,虚拟机必须恢复发起调用的方法的栈帧,包括设置程序计数器指向发起调用方法的下一个指令;如果方法有返回值,虚拟机需要将它压入到发起调用的方法的操作数栈。为了处理Java方法执行期间的异常退出情况,帧数据区还保存一个对此方法异常表的引用。

  1-3、本地方法栈

  本地方法栈与虚拟机栈的作用是相似的,区别仅仅是虚拟机栈为虚拟机执行Java方法,而本地方法栈执行虚拟机使用到的Native方法。

  1-4,、java堆

  Java堆一般是Java虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的,是非线程安全的,在虚拟机启动时创建。

此区域的唯一目的是存放对象实例,几乎所有对象实例和数组(数组实质也是对象)都是在这里分配内存(Java虚拟机规范的原文:The heap is the runtime data area from which memory for all class instance and arrays is allocated.)但是随着虚拟机相关技术的发展,栈上分配等技术将会导致所有对象分配在堆上也不再是那么“绝对”了。  

  因为几乎所有对象都分配在Java堆上,所以Java堆也是垃圾收集器管理的主要区域。从内存角度看,由于现在垃圾收集器基本采用分算法,所欲Java堆又可以细分为:新生代(young area)和老年代(old area),(java8后移除永久代);再细致一点又可以分为Eden、From Survivor 、To Survivor。

  VisualVM的(JAVA8)Visual GC视图如下:

 可以看到Java堆首先被分为新生代和老年代两块区域,新生代又细分为eden、s0、s1三块区域,如此划分应是为了提高虚拟机效率。

  1-5、方法区

  方法区与Java堆一样,也是线程共享的,它被用来存储已被虚拟机加载的类信息、常量、静态变量、即使编译器编译后的代码等数据。java虚拟机对方法区的限制非常宽松,除了和Java堆一样不需要连续的内存和可以选择固定大小或者可扩展外,还可以选择不实现垃圾收集。

 

  1-6、运行时常量池

  运行时常量池是 方法区 的一部分,用于存放编译期间生成的各种字面量和符号引用,这部分内容是在类加载后进入方法区运行时常量池中存放。

java虚拟机笔记-1的更多相关文章

  1. Java虚拟机笔记(五):JVM中对象的分代

    为什么要分代 为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我们要找到哪些对象没用, ...

  2. Java虚拟机笔记(四):垃圾收集器

    前言 前一篇文章介绍了内存的垃圾收集算法,现在介绍下内存回收的具体实现--垃圾收集器. 由于Java虚拟机规范中对垃圾收集器应该如何实现并没有任何规定,因此不同的厂商,不同版本的虚拟机所提供的垃圾收集 ...

  3. Java虚拟机笔记(三):垃圾收集算法

    一.标记-清除(Mark-Sweep)算法 标记清除算法是最基础的收集算法,其他收集算法都是基于这种思想. 标记清除算法分为“标记”和“清除”两个阶段:首先标记出需要回收的对象,标记完成之后统一清除对 ...

  4. Java虚拟机笔记(二):GC垃圾回收和对象的引用

    为什么要了解GC 我们都知道Java开发者在开发过程中是不需要关心对象的回收的,因为Java虚拟机的原因,它会自动回收那些失效的垃圾对象.那我们为什么还要去了解GC和内存分配呢? 答案很简单:当我们需 ...

  5. Java虚拟机笔记(一):类加载机制

    一.概述 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 二.类加载的生命周期 类从被加载到 ...

  6. 深入理解java虚拟机笔记Chapter12

    (本节笔记的线程收录在线程/并发相关的笔记中,未在此处提及) Java内存模型 Java 内存模型主要由以下三部分构成:1 个主内存.n 个线程.n 个工作内存(与线程一一对应) 主内存与工作内存 J ...

  7. Java虚拟机笔记 – JVM 自定义的类加载器的实现和使用2

    1.用户自定义的类加载器: 要创建用户自己的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的findClass(String name)方法即可,该方法根据参数指定类的名 ...

  8. 深入理解Java虚拟机笔记

    1. Java虚拟机所管理的内存 2. 对象创建过程 3. GC收集 4. HotSpot算法的实现 5. 垃圾收集器 6. 对象分配内存与回收细节 7. 类文件结构 8. 虚拟机类加载机制 9.类加 ...

  9. 深入理解java虚拟机笔记之一

    Java的技术体系主要有支撑java程序运行的虚拟机,提供各开发领域接口支持Java API,java编程语言及许多第三方java框架( 如Spring,Structs等)构成. 可以把Java程序设 ...

随机推荐

  1. 实体模型集合对象转换为VO对象集合

    例如: 数据库中查出来的数据为 List<RptDayMonthTarget> List<RptDayMonthTarget> list = targetService.sel ...

  2. vue动态生成表单

    vue动态生成表单 一.下拉框 <!DOCTYPE html> <html> <head> <meta charset="utf-8" / ...

  3. 一、.Net Core 分块上传文件

    一..Net Core 分块上传文件 一.前端实现 @* For more information on enabling MVC for empty projects, visit http://g ...

  4. 基于impi zabbix监控r720 测试过程

    1.F2进入服务器bios 修改network  使这台服务器能够被远程访问. 2.在远程的centos 7 服务器上安装  impitool工具包 #ipmitool -I lanplus -H X ...

  5. LightOJ 1289 LCM from 1 to n(位图标记+素数筛

    https://vjudge.net/contest/324284#problem/B 数学水题,其实就是想写下位图..和状压很像 题意:给n让求lcm(1,2,3,...,n),n<=1e8 ...

  6. JAVA 关于File的使用

    File中常用方法 创建 createNewFile() 在指定位置创建一个空文件,成功就返回true,如果已存在就不创建然后返回false mkdir() 在指定位置创建目录,这只会创建最后一级目录 ...

  7. bzoj1969 [Ahoi2005]LANE 航线规划 树链剖分

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1969 题解 如果我们把整个图边双联通地缩点,那么最终会形成一棵树的样子. 那么在这棵树上,\( ...

  8. HTML表单(来自MDN的总结)

    表单介绍 HTML表单是用户和web站点或应用程序之间交互的主要内容之一.它们允许用户将数据发送到web站点.大多数情况下,数据被发送到web服务器,但是web页面也可以拦截它自己并使用它. HTML ...

  9. 免插件,简单实现上拉加载loading

    上拉加载是前端经常遇到的问题,采用插件往往能够轻松解决,这里介绍一种免插件简单实现上拉加载的方法,参考一下,下面分享一下代码. html <body> <ul> <li& ...

  10. Java初步

    Java的核心优势:跨平台 Java SE:标准版Java EE:企业级Java ME:微型版 源文件(*.java)→编译器→字节码文件(*.class)→(类装载器→字节码校验器→解释器)[JRE ...