深入理解Java虚拟机

Java技术体系

Java体系分为四个平台

  • Java card 运行在小内存上的
  • Java ME 运行在手机上
  • Java SE 完整Java 核心api
  • JavaEE 支持使用多层架构的企业

JVM自身的物理结构

Java 代码编译和执行的整个过程

Java 编译的过程

Java字节码执行的过程

 
Java 代码编译和执行有下面三个过程

  • Java 源码编译
  • 类加载机制‘
  • 类执行机制

下面就分别对着三个过程进行详细的介绍 
Java源码编译机制

  • 分析输入符号表
  • 注解处理
  • 语义分析和生成class文件

流程如下

 
class 文件的由下面的部分组成

  • 结构信息 class文件的一些信息
  • 元数据 Java 源码中声明与常量的信息。
  • 方法信息 语句 表达式对应的信息。

类加载机制 
JVM的类加载时根据ClassLoader及其子类来完成的

下面就对加载结构的几个模块进行介绍 
1)Bootstrap ClassLoader 
负责加载$JAVA_HOME中jre/lib/rt.jar 
2)Extension ClassLoader 
加载扩展功能的一些 jar 包 
3)App ClassLoader 
负责加载classpath中指定的jar包 
4)Custom ClassLoader 
属于应用程序根据自身需要自定义的 ClassLoader,如 Tomcat

类执行机制 
。。。。。。

Java 内存区域与内存溢出

Java将内存分为以下几个运行时数据区

  • 程序计数器
  • Java 虚拟机栈
  • 本地方法栈
  • Java 堆
  • 方法区

下面对几个区域进行介绍 
程序计数器 
利用程序计数器的值选择下一条指令,来实现一些基础功能。每个线程都有独立的程序计数器,各个线程间的程序计数器互不影响 
Java 虚拟机栈 
线程私有的,它的生命周期也与线程相同。 
虚拟机栈描述的是 Java 方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧,栈它是用于支持续虚拟机进行方法调用和方法执行的数据结构。 
Java 虚拟机规范中,对这个区域规定了两种异常情况

  • 如果线程请求的栈深度过大,将抛出StackOverflowError异常。
  • 如果虚拟机无法申请到足够的内存空间,则抛出OutOfMemoryError异常。

栈帧 中存的部分信息

  • 局部变量表
  • 操作数栈
  • 动态连接
  • 方法返回地址

本地方法栈 
虚拟机栈为虚拟机执行 Java 方法服务,而本地方法栈则为使用到的本地操作系统(Native)方法服务。

Java堆 
所有线程共享的一块内存区域,几乎所有的对象实例和数组都是在这一类分配内存. 
而且Java 堆是GC进行内存收集的主要地方.

方法区 
方法区也是各个线程共享的内存区域,它用于存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据

直接内存 
虚拟机运行内存外的内存.

内存溢出 几个特点和测试方法

对象实例化分析 
根据实例一个对象来分析内存的分配

1.Object obj = new Object();
  • obj 会作为引用类型(reference)的数据保存在 Java 栈的本地变量表中
  • Java 堆中保存该引用的实例化对象

类加载机制

类加载到卸载的过程 
加载、验证、准备、解析、初始化、使用和卸载七个阶段 
加载的过程是加载、验证、准备、解析、初始化 这五个阶段, 
有些情况下要使用Java中的绑定 : 绑定指的是把一个方法的调用与方法所在的类(方法主体)关联起来 .绑定分为静态绑定和动态绑定.

  • 静态绑定 即前期绑定,指的是程序在执行前已经被绑定了,此时编译器或其他连接程序实现.
  • 动态绑定 就是晚期绑定,也叫运行时绑定.在运行时根据具体对象的类型进行绑定.

加载 
加载阶段,虚拟机啊需要完成的三件事情

  • 通过全限类名获取定义的二进制字节流
  • 将字节流静态存储结构转化为方法区的运行时数据结构
  • 在Java 堆中生成一个类的Class对象,作为方法区中数据的访问入口

类加载器大致分为三种

  • 启动类加载器(BootstrapClassLoader) 负责加载JDK\jre\li 下的类库
  • 扩展类加载器(Extension ClassLoader) 加载lib\ext目录下类
  • 应用程序加载器 (Application ClassLoader)

几种类加载器的层次关系

 
这种层次关系称为类加载器的双亲委派模型 
双亲委派模型的工作流程

  • 一个类加载器收到一个类加载的请求,它首先不是自己去加载类。而是把这个请求委托给父加载器去完成,依次向上。因此所有的类加载请求最终都应该传递到顶层的启动类加载器中,只有当父类的加载器无法搜索到所需要的类时,子加载器才会主动尝试自己去加载。 
    使用双亲委派的好处

    • Java类随着它的类加载器也具有了一定的优先级的层次关系
    • 例如 Object类时存在\jre\lib下的,所以无论哪个类加载器要加载此类,最终都会委派给启动加载器进行加载,

验证 
验证Class文件字节流符合虚拟机要求 
验证的四个阶段

  • 文件格式的验证 验证字节流是否符合Class文件规范
  • 元数据的验证 对类中的各项数据类型进行语法检验
  • 字节码验证 进行数据流和控制流分析
  • 符号引用验证 对类自身以外的信息进行匹配检验

准备 
为类变量分配内存并设置类变量初始值,在方法区分配

解析 
虚拟机将常量池的符号引用转为直接引用

初始化 
初始化阶段是执行类构造器方法的过程

对Java虚拟机理解的更多相关文章

  1. java虚拟机理解探索1

    以下内容源于个人对<深入java虚拟机>的理解总结 基本概念: java虚拟机可以指一种抽象规范,也可以指一种具体实现,亦可以指一个java虚拟机实例. 虚拟机生命周期: 一个java虚拟 ...

  2. Java虚拟机理解-内存管理

    运行时数据区域 jdk 1.8之前与之后的内存模型有差异,方法区有变化(https://cloud.tencent.com/developer/article/1470519). java的内存数据区 ...

  3. 《深入理解Java虚拟机》类文件结构

    上节学习回顾 在上一节当中,主要以自己的工作环境简单地介绍了一下自身的一些调优或者说是故障处理经验.所谓百变不离其宗,这个宗就是我们解决问题的思路了. 本节学习重点 在前面几章,我们宏观地了解了虚拟机 ...

  4. 《深入理解Java虚拟机》虚拟机性能监控与故障处理工具

    上节学习回顾 从课本章节划分,<垃圾收集器>和<内存分配策略>这两篇随笔同属一章节,主要是从理论+实验的手段来讲解JVM的内存处理机制.好让我们对JVM运行机制有一个良好的概念 ...

  5. 《深入理解Java虚拟机》垃圾收集器

    说起垃圾收集(Garbage Collection,GC),大部分人都把这项技术当做Java语言的伴生产物.事实上,GC的历史远比Java久远,1960年诞生于MIT的Lisp是第一门真正使用内存动态 ...

  6. 《深入理解Java虚拟机》Java内存区域与内存溢出异常

    注:“蓝色加粗字体”为书本原语 先来一张JVM运行时数据区域图,再接下来一一分析各区域功能:   程序计数器 程序计数器(program Counter Register)是一块较小的内存空间,它可以 ...

  7. 《深入理解 java虚拟机》学习笔记

    java内存区域详解 以下内容参考自<深入理解 java虚拟机 JVM高级特性与最佳实践>,其中图片大多取自网络与本书,以供学习和参考.

  8. 理解java虚拟机内存分配堆,栈和方法区

    栈:存放局部变量 堆:存放new出来的对象 方法区:存放类的信息,static变量,常量池(字符串常量) 在堆中,可以说是堆的一部分   创建了一个student类,定义了name属性, id静态变量 ...

  9. JVM内存结构---《深入理解Java虚拟机》学习总结

    Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域的用途各不相同,同时也依据着各自的执行规则,独立的创建和销毁数据. 虚拟机内存的划分,如图所示: 线程之间 ...

随机推荐

  1. Android中去掉标题栏

    在Android中去掉标题栏有三种方法,它们也有各自的特点. 1.在代码里实现 this.requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏 记 ...

  2. Android-okhttp

    在AndroidManifest.xml配置网络访问权限: <!-- 访问网络是危险的行为 所以需要权限 --> <uses-permission android:name=&quo ...

  3. 分形之谢尔宾斯基(Sierpinski)地毯

    前面讲了谢尔宾斯基三角形,和这一节的将把三角形变为正方形,即谢尔宾斯基地毯,它是由瓦茨瓦夫·谢尔宾斯基于1916年提出的一种分形,是自相似集的一种. 谢尔宾斯基地毯的构造与谢尔宾斯基三角形相似,区别仅 ...

  4. 三、Kubernetes之深入了解Pod

      1.yaml格式的Pod配置文件内容及注解 深入Pod之前,首先我们来了解下Pod的yaml整体文件内容及功能注解. 如下: # yaml格式的pod定义文件完整内容: apiVersion: v ...

  5. NW.js安装原生node模块node-printer控制打印机

    1.安装原生node模块 #全局安装nw-gyp npm install -g nw-gyp #设置目标NW.js版本 set npm_config_target=0.31.4 #设置构建架构,ia3 ...

  6. 实验1 单片机IO口应用及数码管显示

    1.   单片机驱动蜂鸣器的实验: a)         说明:Lab51单片机实验板的蜂鸣器连接到单片机的P1.5 b)        基本要求:控制蜂鸣器每2秒响0.5秒. #include &l ...

  7. 【BZOJ1052】 [HAOI2007]覆盖问题

    BZOJ1052 [HAOI2007]覆盖问题 前言 小清新思维题. 最近肯定需要一些思维题挽救我这种碰到题目只会模板的菜鸡. 这题腾空出世? Solution 考虑一下我们二分答案怎么做? 首先转换 ...

  8. 深入理解String类

    1.String str = "eee" 和String str = new String("eee")的区别 先看一小段代码, public static v ...

  9. 暴破助攻提权:ruadmin

    i春秋作家:yangyangwithgnu 1 缘由 千辛万苦拿下的 webshell 不是 www-data 用户就是 networkservice 权限,要想拓展攻击面.扩大战果,提权,是必经之路 ...

  10. 为ElasticSearch添加HTTP基本认证

    ES的HTTP连接没有提供任何的权限控制措施,一旦部署在公共网络就容易有数据泄露的风险,尤其是加上类似elasticsearch-head这样友好的前端界面,简直让你的数据瞬间裸奔在黑客的眼皮底下.项 ...