VM,Virtual Machine 即虚拟机,指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统。

JVM,Java Virtual Machine 即Java虚拟机,在Java编辑器与OS操作系统之间的虚拟处理器,其模拟计算机的各种功能,将编译后的字节码解释成具体平台上的机器指令执行,从而实现Java的“一次编译,到处运行(Write once, run anywhere)

一、基本流程

开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件),再然后字节码被装入内存,一旦字节码进入虚拟机,它就会被解释器解释执行,或者是被即时代码发生器有选择的转换成机器码执行。

在Java平台的结构中, 可以看出,Java虚拟机(JVM) 处在核心的位置,是程序与底层操作系统和硬件无关的关键。

它的下方是移植接口,移植接口由两部分组成:适配器和Java操作系统, 其中依赖于平台的部分称为适配器;JVM 通过移植接口在具体的平台和操作系统上实现;

在JVM 的上方是Java的基本类库和扩展类库以及它们的API, 利用Java API编写的应用程序(application) 和程序(Java applet) 可以在任何Java平台上运行而无需考虑底层平台, 就是因为有Java虚拟机(JVM)实现了程序与操作系统的分离,从而实现了Java 的平台无关性。

JVM在它的生存周期中有一个明确的任务,那就是运行Java程序,因此当Java程序启动的时候,就产生JVM的一个实例;当程序运行结束的时候,该实例也跟着消失了。

二、Jvm结构

1、类加载器(ClassLoader):负责从文件系统或者网络中加载Class信息,加载的类信息存放于一块称为方法区的内存空间。除了类的信息外,方法区中可能还会存放运行时常量池信息,包括字符串字面量和数字常量(这部分常量信息是Class文件中常量池部分的内存映射)

2、方法区(Method Area):用于存储类结构信息的地方,包括常量池、静态变量、构造函数等。虽然JVM规范把方法区描述为堆的一个逻辑部分, 但它却有个别名non-heap(非堆),所以大家不要搞混淆了。方法区还包含一个运行时常量池。

3、java堆(Heap):在虚拟机启动的时候建立,它是java程序最主要的内存工作区域;几乎所有的java对象实例都存放在java堆中;方法区和堆是被所有java线程共享的。

4、jvm栈(Stack):线程私有的内存空间;每当创建一个线程时,JVM就会为这个线程创建一个对应的jvm栈;

5、本地方法栈(Native Method Stack):用于支持native方法的执行,存储了每个native方法调用的状态;jvm栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务;

6、程序计数器(PC Register):线程私有,用于保存当前线程执行的内存地址。由于JVM程序是多线程执行的(线程轮流切换),所以为了保证线程切换回来后,还能恢复到原先状态,就需要一个独立的计数器,记录之前中断的地方;如果正在执行的是Natvie方法,这个计数器值则为空(Undefined)

7、执行引擎:负责执行class文件中包含的字节码指令;

  •  java堆

存放对象实例;完全自动化管理的,通过垃圾回收机制,垃圾对象会被自动清理,而不需要显示的释放;

常见构成:新生代和老年代,Enden区和两个Survivor区(From和to);Java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可;一般按照可扩展来实现的(通过-Xmx和-Xms控制)

在绝大多数情况下,对象首先分配在eden区,在一次新生代回收之后,如果对象还存活,则进入s0或者s1,

每经过一次新生代回收,对象如果存活,它的年龄就会加1。当对象的年龄达到一定条件后,就会被认为是老年对象,从而进入老年代。

java堆、方法区和java栈之间的关系

 package com.jvm;
public class SimpleHeap {
  private int id;
  public SimpleHeap(int id){
    this.id = id;
  }
  public void show(){
    System.out.println("My id is "+id);
  }   public static void main(String[] args) {
    SimpleHeap s1 = new SimpleHeap(1);
    SimpleHeap s2 = new SimpleHeap(2);
    s1.show();
    s2.show();
  }
}

该代码声明了一个类,并在main函数中创建了两个SimpleHeap实例。此时,各对象和局部变量的存放情况如图:

SimpleHeap实例本身分配在堆中,描述SimpleHeap类的信息存放在方法区,main函数中的s1 s2局部变量存放在java栈上,并指向堆中两个实例。

  • java栈

线程私有的内存空间;先进后出的数据结构;主要内容为栈帧(至少包含局部变量表、操作数栈和帧数据区几个部分);每一次函数调用,都会有一个对应的栈帧被压入java栈,每一个函数调用结束,都会有一个栈帧被弹出java栈(进栈出栈)

当前正在执行的函数所对应的帧就是当前帧(位于栈顶),它保存着当前函数的局部变量、中间计算结果等数据;

每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

两种异常状况:

如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常(增大-Xss的值);

如果虚拟机栈可以动态扩展(当前大部分的Java虚拟机都可动态扩展,只不过Java虚拟机规范中也允许固定长度的虚拟机栈),当扩展时无法申请到足够的内存时会抛出OutOfMemoryError异常。

 public static void recursion(){
    count++;
    recursion();
}

局部变量表是栈帧的重要组成部分之一;表中的槽位可以重用;

它用于保存函数的参数以及局部变量,局部变量表中的变量只在当前函数调用中有效,当函数调用结束,随着函数栈帧的弹出销毁,局部变量表也会随之销毁。

由于局部变量表在栈帧之中,因此,如果函数的参数和局部变量很多,会使得局部变量表膨胀,从而每一次函数调用就会占用更多的栈空间, 死循环下,函数的嵌套调用次数减少;

局部变量表中的变量也是垃圾回收根节点,只要被局部变量表中直接或者间接引用的对象都是不会被回收的。

可回收:方法结束变量失去引用后的方法外部,方法内变量被置null失去强引用,变量离开作用域并且再定义新变量复用空间;(销毁变量即可回收)

小问小答

类加载 http://blog.csdn.net/boyupeng/article/details/47951037

概念问题 https://www.toutiao.com/a6421302542316241154/

调优问题 https://www.toutiao.com/a6511998857537126925/

GC问题 https://www.toutiao.com/a6493469044564296205/

JAVA总结--jvm的更多相关文章

  1. java内功 ---- jvm虚拟机原理总结,侧重于虚拟机类加载执行系统

    参考书籍:<深入理解java虚拟机>,三天时间用了八个小时看完,像读一本武侠小说,挺爽. 另外需声明:图片都是从我自己的csdn博客转载,所以虽然有csdn标识,但都是我自己画的图片. j ...

  2. Java虚拟机JVM学习07 类的卸载机制

    Java虚拟机JVM学习07 类的卸载机制 类的生命周期 当Sample类被加载.连接和初始化后,它的生命周期就开始了. 当代表Sample类的Class对象不再被引用,即不可触及时,Class对象就 ...

  3. Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论

    Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论 创建用户自定义的类加载器 要创建用户自定义的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的f ...

  4. Java虚拟机JVM学习05 类加载器的父委托机制

    Java虚拟机JVM学习05 类加载器的父委托机制 类加载器 类加载器用来把类加载到Java虚拟机中. 类加载器的类型 有两种类型的类加载器: 1.JVM自带的加载器: 根类加载器(Bootstrap ...

  5. Java虚拟机JVM学习04 类的初始化

    Java虚拟机JVM学习04 类的初始化 类的初始化 在初始化阶段,Java虚拟机执行类的初始化语句,为类的静态变量赋予初始值. 在程序中,静态变量的初始化有两种途径: 1.在静态变量的声明处进行初始 ...

  6. Java虚拟机JVM学习03 连接过程:验证、准备、解析

    Java虚拟机JVM学习03 连接过程:验证.准备.解析 类被加载后,就进入连接阶段. 连接就是将已经读入到内存的类的二进制数据合并到虚拟机的运行时环境中去. 连接阶段三个步骤:验证.准备和解析. 类 ...

  7. Java虚拟机JVM学习02 类的加载概述

    Java虚拟机JVM学习02 类的加载概述 类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对 ...

  8. Java虚拟机JVM学习01 流程概述

    Java虚拟机JVM学习01 流程概述 Java虚拟机与程序的生命周期 一个运行时的Java虚拟机(JVM)负责运行一个Java程序. 当启动一个Java程序时,一个虚拟机实例诞生:当程序关闭退出,这 ...

  9. Dalvik VM (DVM) 与Java VM (JVM)之间有哪些区别?

    Dalvik虚拟机存在于Android系统,JVM是java虚拟机,两者都是虚拟机,本文就对两者进行比较,讲述它们的不同. Dalvik虚拟机是Google等厂商合作开发的Android移动设备平台的 ...

  10. JAVA的JVM虚拟机工作原理.V.1.0.0

    注意:一下内容纯属个人理解,如有错误,欢迎批评指正. (90度弯腰)谢谢. java在JVM上的运行过程: 1,编辑好的java代码(IDE无报错,测试运行无错误): 2,java源代码通过javac ...

随机推荐

  1. Nacos 快速开始

    原文:https://nacos.io/zh-cn/docs/quick-start.html https://www.jianshu.com/p/16ff6d6db0cf Nacos安装: 1.从 ...

  2. 基于VSFTP的本地YUM源及光盘YUM源搭建

    基于VSFTP的本地YUM源及光盘YUM源搭建  一.yum环境的本地源搭建(基于VSFTP):  1)安装vsftp;     *********************************** ...

  3. POJ-2516-Minimum Cost(网络流, 最小费用最大流)

    链接: https://vjudge.net/problem/POJ-2516 题意: Dearboy, a goods victualer, now comes to a big problem, ...

  4. CSS3——制作带动画效果的小图片

    下了一个软件:ScreenToGif用来截取动态图片,终于可以展示我的小动图啦,嘻嘻,敲开心! main.html <!DOCTYPE html> <html lang=" ...

  5. HTTP content-type及POST提交数据方式

    Content-Type(内容类型),一般指网页中存在的Content-Type,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式.什么编码读取这个文件,这也是一些网页点击的结果却是一个文件 ...

  6. linux运维、架构之路-CentOS6.9安装Zabbix3.4.1

    一.LAMP环境安装 1.环境 [root@m01 ~]# cat /etc/redhat-release CentOS release 6.9 (Final) [root@m01 ~]# uname ...

  7. 【PowerOJ1752&网络流24题】运输问题(费用流)

    题意: 思路: [问题分析] 费用流问题. [建模方法] 把所有仓库看做二分图中顶点Xi,所有零售商店看做二分图中顶点Yi,建立附加源S汇T. 1.从S向每个Xi连一条容量为仓库中货物数量ai,费用为 ...

  8. 3D Computer Grapihcs Using OpenGL - 09 Enable Depth Test

    启用Depth Test OpenGL是个3D绘图API,也就是说不只有xy坐标轴,还有第三个坐标轴z,z轴的方向是垂直于屏幕,指向屏幕内. 靠近人眼的方向是负方向,标准化设备坐标的最小值是-1, 最 ...

  9. JavaScript toFixed()、toExponential、toPrecision方法

    JavaScript toFixed() 定义和用法 toFixed() 方法可把 Number 四舍五入为指定小数位数的数字. 语法 NumberObject.toFixed(num) 参数 描述 ...

  10. Java基础之数组类型

    对于Java,前面的一些基础概念不是很想写,看了看还是从数组开始写吧(毕竟数组是第一个引用类型,相对复杂一点),我也是学了JAVA不是很久,目前看完了JAVA的基础视频,还有JAVA疯狂讲义这本书的大 ...