`

Java虚拟机:JVM中的Stack和Heap

    博客分类:
  • JAVA
阅读更多
  • Java虚拟机:JVM中的Stack和Heap
  • 在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里,我们从JVM的内存管理原理的角度来认识Stack和Heap,并通过这些原理认清Java中静态方法和静态属性的问题。
     
    一般,JVM的内存分为两部分:Stack和Heap。
     
    Stack(栈)是JVM的内存指令区。Stack管理很简单,push一定长度字节的数据或者指令,Stack指针压栈相应的字节位移;pop一定字节长度数据或者指令,Stack指针弹栈。Stack的速度很快,管理很简单,并且每次操作的数据或者指令字节长度是已知的。所以Java 基本数据类型,Java 指令代码,常量都保存在Stack中。
     
    Heap(堆)是JVM的内存数据区。Heap 的管理很复杂,每次分配不定长的内存空间,专门用来保存对象的实例。在Heap 中分配一定的内存来保存对象实例,实际上也只是保存对象实例的属性值,属性的类型和对象本身的类型标记等,并不保存对象的方法(方法是指令,保存在Stack中),在Heap 中分配一定的内存保存对象实例和对象的序列化比较类似。而对象实例在Heap 中分配好以后,需要在Stack中保存一个4字节的Heap 内存地址,用来定位该对象实例在Heap 中的位置,便于找到该对象实例。
     
    由于Stack的内存管理是顺序分配的,而且定长,不存在内存回收问题;而Heap 则是随机分配内存,不定长度,存在内存分配和回收的问题;因此在JVM中另有一个GC进程,定期扫描Heap ,它根据Stack中保存的4字节对象地址扫描Heap ,定位Heap 中这些对象,进行一些优化(例如合并空闲内存块什么的),并且假设Heap 中没有扫描到的区域都是空闲的,统统refresh(实际上是把Stack中丢失了对象地址的无用对象清除了),这就是垃圾收集的过程;
     
     
    JVM的体系结构
     
    我们首先要搞清楚的是什么是数据以及什么是指令。然后要搞清楚对象的方法和对象的属性分别保存在哪里。
     
    1)方法本身是指令的操作码部分,保存在Stack中;
     
    2)方法内部变量作为指令的操作数部分,跟在指令的操作码之后,保存在Stack中(实际上是简单类型保存在Stack中,对象类型在Stack中保存地址,在Heap 中保存值);上述的指令操作码和指令操作数构成了完整的Java 指令。
     
    3)对象实例包括其属性值作为数据,保存在数据区Heap 中。
     
    非静态的对象属性作为对象实例的一部分保存在Heap 中,而对象实例必须通过Stack中保存的地址指针才能访问到。因此能否访问到对象实例以及它的非静态属性值完全取决于能否获得对象实例在Stack中的地址指针。
     
    非静态方法和静态方法的区别:
     
    非静态方法有一个和静态方法很重大的不同:非静态方法有一个隐含的传入参数,该参数是JVM给它的,和我们怎么写代码无关,这个隐含的参数就是对象实例在Stack中的地址指针。因此非静态方法(在Stack中的指令代码)总是可以找到自己的专用数据(在Heap 中的对象属性值)。当然非静态方法也必须获得该隐含参数,因此非静态方法在调用前,必须先new一个对象实例,获得Stack中的地址指针,否则JVM将无法将隐含参数传给非静态方法。
     
    静态方法无此隐含参数,因此也不需要new对象,只要class文件被ClassLoader load进入JVM的Stack,该静态方法即可被调用。当然此时静态方法是存取不到Heap 中的对象属性的。
     
    总结一下该过程:当一个class文件被ClassLoader load进入JVM后,方法指令保存在Stack中,此时Heap 区没有数据。然后程序技术器开始执行指令,如果是静态方法,直接依次执行指令代码,当然此时指令代码是不能访问Heap 数据区的;如果是非静态方法,由于隐含参数没有值,会报错。因此在非静态方法执行前,要先new对象,在Heap 中分配数据,并把Stack中的地址指针交给非静态方法,这样程序技术器依次执行指令,而指令代码此时能够访问到Heap 数据区了。
     
    静态属性和动态属性:
     
    前面提到对象实例以及动态属性都是保存在Heap 中的,而Heap 必须通过Stack中的地址指针才能够被指令(类的方法)访问到。因此可以推断出:静态属性是保存在Stack中的,而不同于动态属性保存在Heap 中。正因为都是在Stack中,而Stack中指令和数据都是定长的,因此很容易算出偏移量,也因此不管什么指令(类的方法),都可以访问到类的静态属性。也正因为静态属性被保存在Stack中,所以具有了全局属性。
     
    在JVM中,静态属性保存在Stack指令内存区,动态属性保存在Heap数据内存区。
     
     
    -------------------------------
     
    二、Java虚拟机体系结构
     
    Java虚拟机由五个部分组成:一组指令集、一组寄存器、一个栈、一个无用单元收集堆(Garbage-collected-heap)、一个方法区域。这五部分是Java虚拟机的逻辑成份,不依赖任何实现技术或组织方式,但它们的功能必须在真实机器上以某种方式实现。
     
    Java语言写的源程序通过Java编译器,编译成与平台无关的‘字节码程序’(.class文件,也就是0,1二进制程序),然后在OS之上的Java解释器中解释执行,而JVM是java的核心和基础,在java编译器和os平台之间的虚拟处理器
    JAVA和JVM运行的原理
     
    1.Java语言运行的过程
     
    Java语言写的源程序通过Java编译器,编译成与平台无关的‘字节码程序’(.class文件,也就是0,1二进制程序),然后在OS之上的Java解释器中解释执行。
     
    也相当与
     
    注:JVM(java虚拟机)包括解释器,不同的JDK虚拟机是相同的,解释器不同。
     
    2.JVM:
     
    JVM是java的核心和基础,在java编译器和os平台之间的虚拟处理器。它是一种利用软件方法实现的抽象的计算机基于下层的操作系统和硬件平台,可以在上面执行java的字节码程序。
     
    java编译器只要面向JVM,生成JVM能理解的代码或字节码文件。Java源文件经编译成字节码程序,通过JVM将每一条指令翻译成不同平台机器码,通过特定平台运行。
     
    JVM执行程序的过程 :
     
    I.加载。class文件
     
    II.管理并分配内存
     
    III.执行垃圾收集
     
    JRE(java运行时环境)由JVM构造的java程序的运行环境 
     
    JVM 原理解释
     
    JVM 全称是 Java Virtual Machine ,Java 虚拟机,这个 JVM 你是看不到的,它存在内存中。我们知道计算机的基本构成是:运算器、控制器、存储器、输入和输出设备,那这个 JVM 也是有这成套的元素,运算器是当然是交给硬件 CPU 还处理了,只是为了适应“一次编译,随处运行”的情况,需要做一个翻译动作,于是就用了JVM 自己的命令集,JVM 的命令集则是可以到处运行的,因为 JVM 做了翻译,根据不同的CPU ,翻译成不同的机器语言。
     
    JVM 是一个内存中的虚拟机,那它的存储就是内存了,我们写的所有类、常量、变量、方法都在内存中。
     
    JVM 的组成部分
     
     
    Class Loader 类加载器
     
    类加载器的作用是加载类文件(.class)到内存,Class Loader 加载的 class 文件是有格式要求的。
     
    类加载的最终产品是位于运行时数据区的堆区的Class对象。
     
    Class对象封装了类在方法区内部的数据结构。 
     
    并且向JAVA程序提供了访问类在方法区内的数据结构。
     
    JVM加载class文件的原理机制
     
    1. Java 中的所有类,必须被装载到 JMV 中才能运行,这个装载工作是由 JVM 中的类装载器完成的,类装载器所做的工作实质是把类文件从硬盘读取到内存中。
     
    2. Java中的类大致分为三种:
     
    a) 系统类
     
    b) 扩展类
     
    c) 由程序员自定义的类
     
    3. 类装载方式,有两种:
     
    a) 隐式装载,程序在运行过程中当碰到通过 new 等方式生成对象时,隐式调用类装载器加载对应的类到jvm中。
     
    b) 显式装载,通过 class.forname() 等方法,显式加载需要的类。  
     
    4. 类加载的动态性体现
     
    一个应用程序总是由n多个类组成,Java 程序启动时,并不是一次把所有的类全部加载后再运行,它总是先把保证程序运行的基础类一次性加载到 JVM 中,其它类等到 JVM 用到的时候再加载,这样的好处是节省了内存的开销。因为java最早就是为嵌入式系统而设计的,内存宝贵,这是一种可以理解的机制,而用到时再加载这也是 Java 动态性的一种体现。
     
    5.Java 类装载器
     
    Java 中的类装载器实质上也是类,功能是把类载入 JVM 中,值得注意的是 JVM 的类装载器并不是一个,而是三个,层次结构如下:
     
          Bootstrap Loader  - 负责加载系统类 
                | 
              - - ExtClassLoader  - 负责加载扩展类 
                              | 
                          - - AppClassLoader  - 负责加载应用类
     
    为什么要有三个类加载器,一方面是分工,各自负责各自的区块,另一方面为了实现委托模型。
     
    6. 类加载器之间是如何协调工作的
     
    前面说了,Java中有三个类加载器,问题就来了,碰到一个类需要加载时,它们之间是如何协调工作的,即 Java 是如何区分一个类该由哪个类加载器来完成呢。
     
    在这里Java采用了委托模型机制,这个机制简单来讲,就是“类装载器有载入类的需求时,会先请示其Parent使用其搜索路径帮忙载入,如果 Parent 找不到,那么才由自己依照自己的搜索路径搜索类”,注意喔,这句话具有递归性。
分享到:
评论

相关推荐

    深入Java虚拟机:JVM中的Stack和Heap

    "深入Java虚拟机:JVM中的Stack和Heap" Java虚拟机(JVM)是一种运行Java字节码的虚拟机环境,它具有自己的内存管理机制。JVM的内存分为两个部分:Stack(栈)和Heap(堆)。 Stack(栈)是JVM的内存指令区,管理...

    Java运行原理与Java虚拟机.pdf

    2. **内存管理**:JVM提供了内存管理机制,包括堆(Heap)和栈(Stack)等区域。堆用于存储对象实例,栈则用于存储局部变量和方法调用的控制信息。此外,JVM还包括垃圾回收(Garbage Collection)机制,自动管理不再使用的...

    JAVA8虚拟机(jvm)规范_Chinese version.rar

    1. **内存模型**:JVM内存分为堆内存(Heap)、栈内存(Stack)、方法区(Method Area)、程序计数器(PC Register)和本地方法栈(Native Method Stack)。堆是存储对象实例的主要区域,栈则用于存储方法调用时的...

    JVM调优总结与ava虚拟机:JVM高级特性与最佳实践(最新第二版)

    1. **内存模型**:Java的内存模型分为堆内存(Heap)、虚拟机栈(JVM Stack)、方法区(Method Area)、本地方法栈(Native Method Stack)和程序计数器(PC Register)。理解这些区域的作用及相互关系是调优的基础...

    30+个视频+深入理解Java虚拟机(jvm优化+内存模型+虚拟机原理)

    根据提供的文件标题、描述、标签以及部分内容,我们可以深入探讨与Java虚拟机(JVM)相关的多个核心知识点。以下是对这些主题的详细阐述: ### Java虚拟机(JVM)概述 Java虚拟机(JVM)是一种用于执行Java字节码的...

    java虚拟机JVM详解ppt

    通过对Java虚拟机JVM的基本概念、架构以及内存管理机制的深入解析,我们可以更好地理解Java程序的执行过程。掌握JVM的工作原理有助于开发者编写更高效、更稳定的Java应用程序,并能有效地解决常见的内存溢出问题。

    Java虚拟机(JVM)面试题 51道.pdf

    4. Java堆(Java Heap):Java虚拟机中内存最大的一块,是被所有线程共享的,几乎所有的对象实例都在这里分配内存。 5. 方法区(Methed Area):用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码...

    深入java虚拟机.pdf

    Java 虚拟机的内存结构包括方法区(method area)和堆(heap)。方法区保存了从类文件中解析出来的信息。堆保存了程序执行时创建的对象。每一个线程都有自己的 PC 寄存器(程序计数器)和 Java 堆栈(Java stack)。...

    Java虚拟机_JVM_参数配置

    JVM内存分为几个主要区域,包括堆内存(Heap)、年轻代(Young Generation)、老年代(Tenured Generation)、方法区(Method Area)和本地方法栈(Native Method Stack)。通过以下参数可以调整这些区域的大小: ...

    Java虚拟机规范中文版.pdf

    Java虚拟机规范还定义了类加载机制,即在JVM启动时或运行过程中动态加载类到内存中。类加载器在运行Java程序时按需加载类,这允许Java程序进行延迟加载,即仅在需要时才加载类,这有助于优化程序的启动时间和运行时...

    Java虚拟机规范中文版

    3. 运行时数据区:JVM在执行Java程序的过程中,需要为其创建一些数据区域,主要包括堆(Heap)、方法区(Method Area)、虚拟机栈(VM Stack)、本地方法栈(Native Method Stack)和程序计数器(Program Counter)...

    JVM内幕:java虚拟机详解

    ### JVM内幕:java虚拟机详解 #### 一、概述 Java虚拟机(JVM)是运行Java应用程序的核心组件,它提供了一个可移植、安全且高性能的环境。本文将深入探讨JVM的内部架构及其各个组成部分的功能。 #### 二、Java虚拟机...

    java虚拟机jvm及Tomcat中的jvm有关内存的设置与调优

    在现代软件开发中,Java虚拟机(JVM)作为执行Java字节码的核心组件,其性能直接影响到Java应用的运行效率与稳定性。特别是在大数据处理场景下,合理设置JVM内存参数显得尤为重要。本文将深入探讨JVM内存管理的基础...

    实战JAVA虚拟机 JVM故障诊断与性能优化

    JVM内存模型包括堆(Heap)、栈(Stack)、方法区(Method Area)、程序计数器(PC Register)和本地方法栈(Native Method Stack)。其中,堆是Java对象的存储空间,栈用于存储方法调用的信息,方法区存储类信息,...

    JAVA文件编译执行与虚拟机(JVM)介绍

    1. **JAVA文件的编译与执行**:JAVA程序首先通过编译器转换为中间代码(字节码),然后由JVM解释执行。 2. **JVM的角色与功能**:JVM作为JAVA程序运行时环境的核心组件,提供了平台无关性、安全性和动态链接等特性。...

    08-Java虚拟机(JVM)面试题-重点.docx

    Java 虚拟机(JVM)面试题-重点 Java 虚拟机(JVM)是 Java 语言的核心组件之一,它提供了一个运行 Java ByteCode 的环境,负责将 Java 代码转换成机器代码,供 CPU 执行。下面是 JVM 的主要组成部分及其作用: ##...

    自己动手写Java虚拟机

    本文主题是通过使用Go语言实现一个简单的Java虚拟机(JVM)。Java虚拟机是Java平台的核心组成部分,它负责运行Java字节码。简单来说,Java代码首先被编译成字节码,然后JVM负责解释执行这些字节码。JVM的主要任务是...

    Java 虚拟机JVM内存模型

    ### Java 虚拟机JVM内存模型知识点 #### 1. JVM概述 ##### 1.1 Java的特性与JVM的应用 Java语言的特性包括跨平台性、面向对象、安全性等。JVM是Java程序能够跨平台运行的关键,它负责将Java源代码转换成与平台无关...

    Java虚拟机(JVM)面试宝典1.pdf

    ### Java虚拟机(JVM)面试宝典核心知识点详解 #### 一、Java内存区域 **1.1 JVM的主要组成部分及其作用**...以上内容涵盖了JVM面试宝典中的关键知识点,对于深入理解Java虚拟机的工作原理及如何进行调优具有重要意义。

Global site tag (gtag.js) - Google Analytics