前情回想

在本专栏的前12篇博客中。 我们主要大致介绍了什么是JVM, 而且具体介绍了class文件的格式。 对于深入理解Java, 或者深入理解运行于JVM上的其它语言, 深入理解class文件格式都是必须的。 假设读者对class文件的格式不是非常熟悉, 在阅读本博客以下的文章之前。 建议先读一下前面的12篇博客。 或者參考其它资料, 熟悉class文件的格式。 

深入理解Java虚拟机究竟是什么 这篇博客中, 我们有提到过, JVM就是一个特殊的进程, 我们运行的java程序。 都运行在一个JVM进程中, 这个进程的作用就是载入class文件, 而且运行class文件里的代码。 当然。 从一个class文件的载入。
到准备好可运行之前。 另一段非常长的路要走, 以后的文章会具体介绍这个过程。 既然虚拟机作为一个虚拟的计算机, 来运行我们的程序, 那么在运行的过程中。 必定要有地方存放我们的代码(class文件)。 在运行的过程中, 总会创建非常多对象, 必须有地方存放这些对象; 在运行的过程中, 还须要保存一些运行的状态。 比方, 将要运行哪个方法, 当前方法运行完毕之后, 要返回到哪个方法等信息。 所以, 必须有一个地方来保持运行的状态。

上面的描写叙述中, “地方”指的当然就是内存区域, 程序运行起来之后。 就是一个动态的过程,
必须合理的划分内存区域。 来存放各种数据。 所以。 在本文中, 将会具体介绍JVM的运行时数据区。

 

JVM体系结构和运行时数据区概述

要理解JVM的运行时数据区。 必须先要理解JVM的体系结构, 由于虚拟机的体系结构基本上解释了“为什么会有这些运行时数据区” 。 在深入理解Java虚拟机究竟是什么 这篇文章中也简单的提到过JVM的体系机构, 这里再具体的解说一下。 JVM的体系结构例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhbmdqZ19ibG9n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

由此可见, 运行时数据区的划分。 是和JVM的体系结构相关的。 本文主要介绍运行时数据区的划分, 对体系结构不做深入的解说。 简单概括一下, 类载入器子系统用于将class文件载入到虚拟机的运行时数据区中(准确的说应该是方法区) 。 能够觉得运行引擎是字节码的运行机制, 一个线程能够看做是一个运行引擎的实例。 以下介绍运行时数据区:

JVM运行时数据区

方法区

在字面意思上。 “方法区”这个词会让人产生误解。由于方法区存放的不仅仅是方法, 它存放的是类型信息。我们在敲代码的时候, 差点儿总是在和类。 对象打交道, 我们知道依据一个类能够创建对象。 一般来说。 我们操纵的是对象。 訪问对象的属性。 调用对象的方法等, 可是我们要思考这样一个问题, 虚拟机依据什么信息知道怎样创建对象的呢? 当然是依据这个对象的类型信息, 可是这个类型信息在哪里呢?如今我们知道是在方法区中。 那么类型信息是被谁载入到方法区中的呢?由上面的体系结构图,
我们能够知道是类载入器子系统?那么所谓的类型信息, 都包括什么信息呢?这些信息又是怎样存放的呢?这里的类型信息, 能够笼统的觉得就是我们前面解说过的一个class文件,类载入器子系统将会提取class文件里面的类型信息,并将这些类型信息存放到方法区中。

 至于方法区中怎样存放一个类型数据, 是和JVM的具体实现相关的。 可是无论怎样实现, 一个类的类型信息总是会包括例如以下信息:

类的全限定名
当前类的直接父类的全限定名
这个类是接口类型, 类类型。 还是枚举类型
类的訪问修饰符信息
当前类型的超接口的全限定名
当前类型的常量池
字段信息
方法信息

假设对class文件格式比較熟悉的话。 能够看出, 这些信息都是在class文件里描写叙述过的。 由于我们无法看到类型信息具体是怎样存储的。 可是大致能够将类型信息看做一个class文件, 这有助于我们的理解。

以下再次列出class文件结构的表格。读者能够对照class文件里的内容到类型数据上。 该表中的各种数据已经在前面的博客中具体解说过:

 类型数据中。除了这些基本信息外, 类型信息还包括以下两个方面:

一个到类的ClassLoader对象的引用
一个到表示该类的Class实例对象的引用

静态变量存储区

由于之前的博客中具体介绍过class文件的格式, 对上面的一些基本信息我们可能比較熟悉。 可是对这两种信息就比較陌生了。

事实上说来也简单,每一个class都是被一个类载入器载入到方法区的, 类型信息中的到类的ClassLoader对象的引用, 表明了当前的类是被哪个类载入器载入的, 这个信息同一时候也标示了当前的类型的名称空间。 

每当一个class文件被成功的载入到方法区中, JVM总会创建一个Class对象, 来唯一标示这个类。

这个Class对象能够看做是类载入过程的产物。 由于它描写叙述了整个类型信息。 而Java中的反射也是针对的类型信息。 所以这个Class对象是反射的基石。 大多数反射API都是依据Class对象来实现的。  

而静态变量也是存在于类型信息中, 能够这么说, 类型信息中, 会有专门的区域存放类的静态变量。 与存在于对象中的实例变量不同, 静态变量存在于类型数据中, 每一个类型仅仅有一份。所以也叫类变量。 

方法区是一个相对来说比較固定的内存区, 由于它存放的是类型信息, 而类型信息在被载入到方法区中之后, 除了必要的连接和初始化。 一般不会有较大修改。普通情况下, JVM也不会卸载类型信息。 所以方法区也能够称为JVM的静态区。 一个类型的生命周期一般就是整个程序的生命周期。 这也是为什么要慎用静态变量的原因所在, 由于静态变量随类型信息存放在方法区中。 生命周期非常长, 假设使用不当。 非常easy造成内存泄露。

一个JVM实例中仅仅存在一个方法区, 方法区中的全部类型数据被全部线程共享。

方法区是存放类型数据的, 而堆则是存放运行时产生的对象的。 和C++不同的是。 Java仅仅能在堆中存放对象。 而不能在栈上分配对象, 全部运行时产生的对象全部都存放于堆中, 包括数组。

我们知道, 在Java中, 数组也是对象。一个JVM实例中仅仅有一个堆, 全部线程共享堆中的数据(对象) 。 

Java虚拟机支持几种不同的创建对象的指令, 如new 。 anewarray等。 这些指令运行的结果就是在堆中分配内存。 并创建对象。 可是Java虚拟机的指令集中并不包括不论什么释放内存的指令, 因而我们也就不能手动释放内存。 全部被创建的对象都会被一个叫做垃圾收集器(GC)的模块自己主动回收。 垃圾收集器有不同的实现方式, 他们以 特定的方式推断对象是否过期, 并以特定的方式对对象进行回收, 关于垃圾收集的话题不是本文的重点, 这里就不多说了。
我们仅仅要知道:全部创建的对象都存在堆中。 而垃圾收集器会自己主动回收过期的对象。 所以,JVM的堆区是垃圾收集器的“重点管理区” 。

Java栈

Java栈是一个线程的运行区域, 它保存着一个线程中的方法的调用状态, 也能够说, 一个Java线程的运行状态。 都由一个Java栈来保存。 在这个栈中, 每一方法相应一个栈帧, 请注意区分栈帧和栈这两个概念。

栈指的是整个线程的运行栈, 栈帧是栈中的一个单位, 每一个方法相应一个栈帧。 JVM会对Java栈运行两种操作: 压栈和出栈。 这两种操作在运行时都是以帧(栈帧)为单位的。 当调用了一个新的方法, 就会压入一个栈帧, 当一个方法调用完毕,
就会弹出这种方法的栈帧, 回到调用者的栈帧。 

举例来说。 假设方法a调用了方法b, 而方法b中调用了方法c。 这个过程中的方法调用和返回的装状态是这种(当中图中两条虚线之间表示Java栈,每一个方块表示一个特定方法的栈帧)

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhbmdqZ19ibG9n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

Java栈上的全部数据都是线程私有的, 也就是说, 每一个线程都会有自己的Java栈, 不会相互訪问其它Java栈中的数据。 

PC寄存器

pc寄存器用于存放一条指令的地址, 这条指令就是虚拟机要运行的下一条指令。pc寄存器和线程相关联, 每一个线程都有一个PC寄存器。

本地方法栈

我们知道Java能够和C/C++互调。假设当前线程运行的代码是C/C++写的本地代码。 那么这些方法就在本地方法栈中运行。而不会在Java栈中运行, Java栈中仅仅运行Java方法。

深入理解Java执行时数据区的更多相关文章

  1. 《Java虚拟机原理图解》3、JVM执行时数据区

    [last updated :2014/11/7]     JVM执行时数据区(JVM Runtime Area)事实上就是指JVM在执行期间,其对计算机内存空间的划分和分配.本文将通过下面几个话题来 ...

  2. Jvm基础(1)-Java运行时数据区

    最近在看<深入理解Java虚拟机>,里面讲到了Java运行时数据区,这是Jvm基本知识,把读书笔记记录在此.这些知识属于常识,都能查到的,如果我有理解不对的地方,还请指出. 首先把图贴上来 ...

  3. 读书笔记-浅析Java运行时数据区

    作为一个 Java 为主语言的程序员,我偶尔也需要 用 C/C++ 写程序,在使用时让我很烦恼的一件事情就是需要对 new 出来的对象进行 delete/free 操作,我老是担心忘了这件事情,从而导 ...

  4. 【转】Java运行时数据区简介及堆与栈的区别

    理解JVM运行时的数据区是Java编程中的进阶部分.我们在开发中都遇到过一个很头疼的问题就是OutOfMemoryError(内存溢出错误),但是如果我们了解JVM的内部实现和其运行时的数据区的工作机 ...

  5. 一个“Hello World”理解JVM运行时数据区

    先上一张JVM体系结构图: 1)运行时数据区:经过编译生成的字节码文件(class文件),由class loader(类加载子系统)加载后交给执行引擎执行.在执行引擎执行的过程中产生的数据会存储在一块 ...

  6. Java 运行时数据区

    写在前面 本文描述的有关于 JVM 的运行时数据区是基于 HotSpot 虚拟机. 概述 JVM 在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以 ...

  7. Java 运行时数据区和内存模型

    运行时数据区是指对 JVM 运行过程中涉及到的内存根据功能.目的进行的划分,而内存模型可以理解为对内存进行存取操作的过程定义.总是有人望文生义的将前者描述为 "Java 内存模型" ...

  8. Java运行时数据区

    目录 1. 概述 2. Java内存结构 3. 程序计数器 4. Java虚拟机栈 5. 本地方法栈 6. 堆 7. 方法区 8. 运行时常量池 9. 直接内存 10. 总结 1. 概述 作为日常的J ...

  9. JVM之Java运行时数据区(线程隔离区)

    来源 JVM会在会在执行Java程序过程中把所管理的内存划分为若干区域,主要包括程序计数器(Program Counter Register),虚拟机栈(VM Stack),本地方法栈(Native ...

随机推荐

  1. 【BZOJ 1076】[SCOI2008]奖励关(期望)

    Description 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物, 每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的 ...

  2. 在Ubuntu 16.04 LTS上用g++和gcc编译C/C++代码错误提示“.../x86_64-linux-gnu/crt1.o: ELF section name out of range”

    (有一些图片我是直接从个人的CSDN博客上复制来的) 最近一个多月来,我曾经多次尝试在Ubuntu 16.04 LTS上使用g++和gcc(这俩好像合起来叫MinGW?)来编译C/C++代码,但是在解 ...

  3. NGINX模块(一)

    [NGINX核心模块] 1.主模块 该模块包含一些Nginx的基本控制功能. 指令1:daemon 语法:daemon on | off 默认值:on daemon off; 说明:生产环境中不要使用 ...

  4. python 监控oracle 数据库

    import cx_Oracle import os db = cx_Oracle.connect('**********') print "Show Oracle Version: &qu ...

  5. hdu 2295 dlx重复覆盖+二分答案

    题目大意: 有一堆雷达工作站,安放至多k个人在这些工作站中,找到一个最小的雷达监控半径可以使k个工作人所在的雷达工作站覆盖所有城市 二分半径的答案,每次利用dlx的重复覆盖来判断这个答案是否正确 #i ...

  6. Java图片缩略图裁剪水印缩放旋转压缩转格式-Thumbnailator图像处理

    前言 java开发中经常遇到对图片的处理,JDK中也提供了对应的工具类,不过处理起来很麻烦,Thumbnailator是一个优秀的图片处理的开源Java类库,处理效果远比Java API的好,从API ...

  7. 谈谈APP架构选型:React Native还是HBuilder

    原文链接 导读:最近公司的一款新产品APP要进行研发,老大的意思想用H5来做混合APP以达到高效敏捷开发的目的.我自然就开始进行各种技术选型的调研,这里重点想说的是我最后挑选出的2款hybrid ap ...

  8. Event Logging 技术简介

    https://blog.csdn.net/xiliang_pan/article/details/41805023

  9. Django学习之 - 基础部分

    学习记录参考: 讲师博客:http://www.cnblogs.com/wupeiqi/articles/5433893.html 老男孩博客:http://oldboy.blog.51cto.com ...

  10. Baby Step Giant Step model

    ******************************************** */ #include <stdio.h> #include <string.h> # ...