JVM的优势

Java的跨平台性

一次编译,到处运行

JVM跨语言

举个例子

将groovy编译之后的class文件用jvm运行

  1. 先配置好groovy环境

  2. 新建HelloWorld.groovy

    class HelloWorld {
    static main(args) {
    println "hello groovy...";
    }
    }
  3. 将其编译成class文件

    groovyc HelloWorld.groovy

  4. 用java命令运行groovy编译出来的HelloWorld.class文件

    (注:全局搜索groovy-all-xxxx.jar的jar包,将其路径作为classpath后的参数)

    java -classpath "E:\codingEnvironment\IntelliJ IDEA 2019.1.3\lib\groovy-all-2.4.15.jar;." HelloWorld

JVM整体结构

HotSpot VM

  1. 方法区和堆区是所有线程共享的内存区域;

  2. Java栈又叫做jvm虚拟机栈。

  3. 执行引擎等同于翻译class文件的语言翻译器。

  4. 方法区(永久代)在jdk8中又叫做元空间

    Metaspace

    • 方法区用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器(JIT编译器,英文写作Just-In-Time Compiler)编译后的代码等数据。
    • 虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做 Non-Heap(非堆),目的应该是与 Java 堆区分开来。

运行时数据区

概述

堆内存:保存所有引用数据的真实信息;

栈内存:基本类型、运算、指向堆内存的指针;

方法区:所以定义的方法的信息都保存方法区中,属于共享区;

程序计数器:是一个非常小的内存空间,用来保证程序依次执行;

本地方法栈:每一次执行递归方法的时候,都会将上一个方法入栈;

方法区(Method Area)

1. 什么是方法区(Method Area)?

方法区(Method Area)与Java堆一样,是各个线程共享的内存区域。

2.方法区(Method Area)存储什么?

它存储已被Java虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等

域信息(成员变量)和方法信息可以看成在类型信息内

2.1 类信息

对每个加载的类型(类class、接口interface、枚举enum、注解annotation),JVM必须在方法区中存储以下类型信息:

  • 这个类型的完整有效名称(全名=包名.类名)
  • 这个类型直接父类的完整有效名称( java.lang.Object除外,其他类型若没有声明父类,默认父类是Object)
  • 这个类型的修饰符(public、abstract、final的某个子集)
  • 这个类型直接接口的一个有序列表

    除此之外还方法区(Method Area)存储类信息还有
  • 类型的常量池( constant pool)
  • 域(Field)信息
  • 方法(Method)信息
  • 除了常量外的所有静态(static)变量

方法区(Method Area)存储类信息请参考:参考博客

2.2 常量
  • static final修饰的成员变量都存储于 方法区(Method Area)中
2.3 静态变量
  • 静态变量又称为类变量,类中被static修饰的成员变量都是静态变量(类变量)
  • 静态变量之所以又称为类变量,是因为静态变量和类关联在一起,随着类的加载而存在于方法区(而不是堆中)
  • 八种基本数据类型(byte、short、int、long、float、double、char、boolean)的静态变量会在方法区开辟空间,并将对应的值存储在方法方法区,对于引用类型的静态变量如果未用new关键字为引用类型的静态变量分配对象(如:static Object obj;)那么对象的引用obj会存储在方法区中,并为其指定默认值null;若,对于引用类型的静态变量如果用new关键字为引用类型的静态变量分配对象(如:static Person person = new Person();),那么对象的引用person 会存储在方法区中,并且该对象在堆中的地址也会存储在方法区中(注意此时静态变量只存储了对象的堆地址,而对象本身仍在堆内存中);这个过程还涉及到静态变量初始化问题,可以参考博客:静态变量初始化相关
2.4 方法(Method)
  • 程序运行时会加载类编译生成的字节码,这个过程中静态变量(类变量)和静态方法普通方法对应的字节码加载到方法区。
  • 但是!!!方法区中没有实例变量,这是因为,类加载先于对应类对象的产生,而实例变量是和对象关联在一起的,没有对象就不存在实例变量,类加载时没有对象,所以方法区中没有实例变量
  • 静态变量(类变量)和静态方法普通方法在方法区(Method Area)存储方式是有区别的

栈(Stack)

栈(Stack):线程私有的内存区域

  • 每个方法(Method)执行时,都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口信息等
  • 栈中所存储的变量和引用都是局部的(即:定义在方法体中的变量或者引用),局部变量和引用都在栈中(包括final的局部变量)
  • 八种基本数据类型(byte、short、int、long、float、double、char、boolean)的局部变量(定义在方法体中的基本数据类型的变量)在栈中存储的是它们对应的值
  • 栈中还存储局部的对象的引用(定义在方法体中的引用类型的变量)对象的引用并不是对象本身,而是对象在堆中的地址,换句话说,局部的对象的引用所指对象在堆中的地址在存储在了栈中。当然,如果对象的引用没有指向具体的对象,对象的引用则是null

Java堆(Java Heap)

Java堆(Java Heap) :被所有线程共享的一块内存区域,在虚拟机启动时创建。Java堆(Java Heap)唯一目的就是存放对象实例。所有的对象实例及数组都要在Java堆(Java Heap)上分配内存空间。

  • 关键字new产生的所有对象都存储于Java堆(Java Heap)
  • !!! 实例变量(非static修饰的成员变量)和对象关联在一起,所以实例变量也在堆中
  • java数组也在堆中开辟内存空间

栈、堆和方法区的关系

Java代码大致执行流程

java源程序--编译javac-->字节码文件.class-->类装载子系统生成反射类(存入方法区)--->运行时数据区(五大块儿)--->执行引擎-->解释执行+编译执行(JIT)-->操作系统(Win,Linux,Mac JVM)

作用

将高级语言转化为机器能听得懂的机器指令

Hotspot中方法区的变动

关于方法区的结构,在过去的版本jdk1.6/1.7/1.8当中均有变动,故在此提前声明:

  • jdk1.6及之前:有永久代(permanent generation) ,静态变量、字符串常量池存放在 永久代上。
  • jdk1.7:有永久代,但已经逐步“去永久代”,字符串常量池、静态变量移除,保存在堆中。注意:
  • jdk1.8及之后: 无永久代,类型信息、字段、方法、常量保存在本地内存的元空间,但字符串常量池、静态变量仍留在堆空间.

JDK6

JDK7

注意:

jdk1.8及之后: 无永久代,类型信息、字段、方法、常量保存在本地内存的元空间。

但字符串常量池、静态变量仍留在堆空间。

除此之外,元空间(或称方法区),不再使用虚拟机内存,而是使用本地内存。

JDK8

参考资料

JVM_01 简介 - 傲娇的大王 - 博客园

(3条消息)JVM学习笔记(三)------内存管理和垃圾回收_走向架构师之路-CSDN博客

(3条消息)Java虚拟机(JVM)面试题(2020最新版)_ThinkWon的博客-CSDN博客

(4条消息)Java方法区、栈及堆_蜗牛-CSDN博客

Jvm垃圾回收器(终结篇) - 不二尘 - 博客园

24个Jvm面试题总结及答案_ITPUB博客

JVM-概述和内存区域的更多相关文章

  1. JVM中有哪些内存区域,分别是用来干什么的

    前言 之前我们探讨过一个.class文件是如何被加载到jvm中的.但是jvm内又是如何划分内存的呢?这个内被加载到了那一块内存中?jvm内存划分也是面试当中必被问到的一个面试题. 什么是jvm内存区域 ...

  2. JVM之Java内存区域

    JVM之Java内存区域 世界上并没有完美的程序,但我们并不因此而沮丧,因为写程序本来就是一个不断追求完美的过程. 一.JAVA内存区域 谈及JAVA虚拟机运行时数据区域就不得不祭出这张经典的图了: ...

  3. JVM总结之内存区域

    Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,有的区域是线程共享的,有的区域是线程隔离的.如下图: 程序计数器 程序计数器(Progra ...

  4. 深入理解JVM - 1 - Java内存区域划分

    作者:梦工厂链接:https://www.jianshu.com/p/7ebbe102c1ae来源:简书简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处. Java与C++之间有一堵 ...

  5. JVM运行时内存区域

    JVM运行java程序时会将内存划分为若干个不同的数据区域: (1)程序计数器: 1.占用内存空间不大. 2.程序计数器相当于JVM所执行的字节码(jvm指令)的“行号指示器”,通过程序计数器的“值” ...

  6. 理解JVM之Java内存区域

    Java虚拟机运行时数据区分为以下几个部分: 方法区.虚拟机栈.本地方法栈.堆.程序计数器.如下图所示: 一.程序计数器 程序计数器可看作当前线程所执行的字节码行号指示器,字节码解释器工作时就是通过改 ...

  7. 史上最详细JVM,Java内存区域讲解

    本人免费整理了Java高级资料,一共30G,需要自己领取:传送门:https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q 运行时数据区域 JVM载执行Jav ...

  8. 学习jvm(一)--java内存区域

    前言 通过学习深入理解java虚拟机的教程,以及自己在网上的查询的资料,做一个对jvm学习过程中的小总结. 本文章内容首先讲解java的内存分布区域,之后讲内存的分配原则以及内存的监控工具.再下来会着 ...

  9. JVM:Java内存区域与内存溢出异常

    Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁时间,有些区域随着虚拟机进程的启动而存在,有些区域依赖用户线程的启动和 ...

  10. JVM笔记3-java内存区域之运行时常量池

    1.运行时常量池属于线程共享区中的方法区. 2.运行时常量池用于编译期生成的各种自变量,符号引用,这部分内用将在类加载后接入方法区的运行时常量池中存放. 看如下代码所示,如图: public clas ...

随机推荐

  1. css3新属性position: sticky 一分钟实现 导航栏悬停功能

    css3新属性position: sticky 一分钟实现 导航栏悬停功能 前言 正文 前言 想必很多前端小伙伴经常会在开发中遇到这样一个需求,就是在下划时,导航栏悬停在屏幕最上方,例如咱们的csdn ...

  2. 第3章 Hive数据类型

    第3章 Hive数据类型 3.1 基本数据类型 对于Hive的String类型相当于数据库的varchar类型,该类型是一个可变的字符串,不过它不能声明其中最多能存储多少个字符,理论上它可以存储2GB ...

  3. 结对项目 实现自动生成四则运算题目的程序 (C++)

    本次作业由 陈余 与 郭奕材 结对完成 零.github地址: https://github.com/King-Authur/-Automatically-generate-four-arithmet ...

  4. PyTorch学习笔记及问题处理

    1.torch.nn.state_dict(): 返回一个字典,保存着module的所有状态(state). parameters和persistent_buffers都会包含在字典中,字典的key就 ...

  5. IDEA常用快捷键Mac os和Windows对照--用到了就会更新

    之前公司用了一段的MacBookPro,离职后自己入手了一台MacBookPro.但是现在的公司中使用的电脑是古老的win7,两个系统的键盘有些许差别,而且快捷键也略有不同.最近因为疫情影响,在家远程 ...

  6. CF1271C Shawarma Tent 题解

    通过分析样例可以发现,离学校越近的地点经过的路线也会越多,因此我们只要考虑学校周围的八个点即可.而且可以发现,对于一个点,路线会经过这个点的节点是确定的.因此在输入的时候可以统计学校周围八个节点被经过 ...

  7. Redis高可用——副本机制

    目录 概念 配置 同步方式 起点 主从握手 部分同步 完全同步 执行完全同步判断条件 完全同步代码实现 为实现Redis服务的高可用,Redis官方为我们提供了副本机制(或称主从复制)和哨兵机制.副本 ...

  8. java最简单的知识之创建一个简单的windows窗口,利用Frame类

    作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985 QQ986945193 微博:http://weibo.com/mcxiaobing 首先给大家看一下 ...

  9. 教你如何在linux操作系统下玩【俄罗斯方块】高清+语音教程

    主讲人小冰QQ:986945193 新浪微博:http://weibo.com/mcxiaobing 百度贴吧:忆驹家族小冰 腾讯微博:http://t.qq.com/q986945193 高清视频 ...

  10. ract-native常用命令

    1.新建项目:react-native init AwesomeProject 2.运动项目 cd AwesomeProject react-native run-ios 3.添加第三方插件: yar ...