<<深入Java虚拟机>>-第二章-Java内存区域-学习笔记

Java运行时内存区域

  Java虚拟机在运行Java程序的时候会将它所管理的内存区域划分为多个不同的区域。每个区域都有自己的用途,创建以及销毁的时间。有的随着虚拟机的启动而存在,有的则是依赖用户线程来启动和销毁。

  1. 程序计数器

     程序计数器是一块很小的区域,可以看做是用来表示线程所执行到字节码的某一行的行号指示器。

     在Java虚拟机中,多线程是线程之间轮流切换并分配处理器的执行时间来实现的,为了线程切换之后能够继续回到之前的代码行继续执行,所以每个线程都有一个“线程私有”的程序计数器。

     如果线程正在执行的是一个Java方法,则计数器记录的就是正在执行的虚拟机字节码指令的地址。如果正在执行的是一个Native方法,则这个计数器为空。

  2. Java虚拟机栈

     Java虚拟机栈也是线程私有的,生命周期与线程相同。

     每个方法在被执行的时候都会创建一个栈帧,用于存储局部变量表、操作栈、动态链接、方法出口等信息。

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

  3. 本地方法栈

     本地方法栈与虚拟机栈类似的,虚拟机栈为虚拟机执行Java方法服务,本地方法栈为虚拟机使用到的Native方法服务。

     Sun HotSpot虚拟机就直接将本地方法栈和虚拟机栈合二为一。

  4. Java堆

     Java堆(Java Heap)是Java虚拟机所管理的内存中最大的一块。

     Java堆是被所有的线程共享的一块区域,在虚拟机启动时候创建。此区域的作用就是存放对象实例。

    Java堆还可以细分为:新生代和老年代。不论如何划分,存放的依然是对象,划分的目的是为了更快的回收内存或者分配内存。

  5. 方法区

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

     方法区中用于存储已经被虚拟机加载的类的信息、常量、静态变量、即时编译后的代码等数据。

    虚拟机垃圾收集行为在这个区域很少出现,在这个区域的内存回收目标主要是对常量池的回收和对类型的卸载。

    • 运行时常量池

       运行时常量池是方法区的一部分。Class类中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池,用于存放编译期生成各种字面量和符号引用,这部分内容会在类加载之后存放到运行时常量池中。

       运行时常量池相较于Class文件常量池的一个重要特征是具备动态性。常量并不一定是只在编译期产生,运行期间也可以将新的常量放入到池中,比如String类的intern()方法。

直接内存

   直接内存并不是虚拟机运行时数据区域的一部分。直接内存是在Java加入了NIO之后出现的,NIO引入了一种基于信道(Channel)与缓冲区(Buffer)的I/O方式,它可以食用Native函数库直接分配堆外内存,然后通过存放在Java堆里的一个DirectByteBuffer对象作为这块内存的引用进行操作。

对象访问

   对于Object obj = new Object();来说

   Object obj将会反应到Java栈的本地变量表中,作为一个reference类型的数据出现。而new Object()这部分就会反应到Java堆中,形成一块存储了Object类型所有实例数据值的结构化内存。在Java堆中还必须包含能查到此对象类型数据(如对象类型、父类、实现的接口、方法等)的地址信息,这些类型数据则存储在方法区中。

   在Java虚拟机规范中reference类型是指向对象的一个引用,不同的虚拟机实现的对象的引用方式不同,主流的访问方式有两种:使用句柄和直接指针。

    • 使用句柄   

       Java堆中会划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址,而句柄中包含了对象的实例数据和类型数据各自的具体地址信息。

    • 直接指针

      使用直接指针的访问方式,reference中存放的就直接是对象的地址。

  两种访问方式优缺点:

    使用句柄访问方式的最大好处就是reference中存放的是稳定的句柄地址,在对象被移动(垃圾收集时移动对象时非常普遍的行为)时只需要修改句柄中的实例数据指针,而reference本身不用修改。

    使用直接指针访问方式的最大好处就是速度更快,它节省了中间一次指针定位的时间开销,对象的访问在Java中非常频繁,这类开销积少成多也是非常可观的执行成本。

    各个厂商的虚拟机不同,Sun HotSpot虚拟机采用的是直接指针访问方式进行对象的访问。

时间: 2024-08-08 06:11:13

<<深入Java虚拟机>>-第二章-Java内存区域-学习笔记的相关文章

java虚拟机 第二章Java内存区域与内存溢出异常

1.运行时数据区域 1.1.程序计数器 线程私有,当前线程所执行的字节码行号指示器, Java虚拟机的多线程是通过线程轮流切换处理器执行时间的方式来分配 1.2.Java虚拟机栈 线程私有,,虚拟机的局部变量表每个方法在执行的时候都会创建栈帧用于存储局部变量,操作数栈,动态链接方法出口等信息,每个方法从开始到结束 对应着一个栈帧从入栈到出栈的过程, 1.3.本地方法栈 线程私有,本地方法栈是为虚拟机执行native方法服务,有的虚拟机奖本地方法栈与虚拟机栈合二为一. 1.4.Java堆 GC堆,

深入理解java虚拟机-第二章

第2章 Java内存区域与内存溢出异常 运行数据区域 1.程序计数器(Program Counter Register) 是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器. 2.Java虚拟机栈(Stack)线程私有,每一个方法调用时都会创建一个栈帧(Stack Frame)用于存储局部变量表.操作数栈.动态链接.方法出口等信息.局部变量存放了编译期可知的各种基本数据类型(boolean,byte,char,short,int,float,long,double).对象引用(

Java虚拟机(JVM)内存区域

        Java虚拟机内存区域分为五部分:程序计数器.Java虚拟机栈.本地方法栈.堆.方法区.其中程序计数器.Java虚拟机栈.本地方法栈属于线程私有内存区,其生命周期与线程相同,随线程的产生而产生,随线程的消亡而消亡.这几个区域的内存在方法或线程结束时,自然就跟着回收了.因此这三个区域的内存分配和回收具有确定性,不需要考虑内存回收的问题.而Java堆和方法区属于线程共享内存区,所有线程都可以访问.只有在程序运行期间才能知道创建哪些对象,因此这两个区域的内存分配和回收都是动态的,也是垃

2016021801 - Java内存区域学习笔记

根据<深入理解java虚拟机>学习归纳整理学习笔记 程序计数器 用途:当前线程的字节码文件的行号指示器.(当前机场负责控制飞机降落的空管员:当前线程表示当前机场, 所执行的字节码等同于被等待允许降落的飞机,行号指示器好比下达允许降落指令的空管员) 线程私有(每个机场都有属于自己的空管员,不同机场的空管员相互独立,互不影响) 类比:某个机场(线程)负责控制航班降落(被执行的字节码)的空管员(行号指示器): 每个机场都有属于自己的空管员: 异常:没有.(机场有没有飞机降落,飞机降落过程发生故障,和

《深入理解Java虚拟机》笔记 第二章 各内存区域溢出形式

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

Java虚拟机系列之Java内存结构简介

本文我们将讲解Java虚拟机中各个区域以及各个区域的作用. 一.程序计数器什么是程序计数器,有什么作用?程序技术器是一块比较小的内存区域,主要当做是线程中所执行的字节码的行号指示器,字节码解释器工作时就是通过改变这个计数器的值来选取下一个执行的字节码命令,分支.循环.跳转等基础功能都是依赖这个程序计数器来完成. 有什么特点?Java虚拟机中的多线程是通过线程轮流切换分配处理器执行时间的方式来实现的,所以为了线程切换后能恢复到正确的执行位置,每条线程都需要一个独立的程序计数器,各条线程之间计数器互

《深入理解Java虚拟机》读书笔记---第二章 Java内存区域与内存溢出异常

Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来.这一章就是给大家介绍Java虚拟机内存的各个区域,讲解这些区域的作用,服务对象以及其中可能产生的问题. 1.运行时数据区域 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域. 1.1程序计数器 程序计数器(Program Counter Register)是一块较小的内存空间,它的作用可以看作是当前线程所执行的字节码的行号指示器.在虚拟机的概念模型中里,字

Java虚拟机2:Java内存区域及对象

http://www.cnblogs.com/xrq730/p/4827590.html 几个计算机的概念 为以后写文章考虑,也为巩固自己的知识和一些基本概念,这里要理清楚几个计算机中的概念. 1.计算机存储单位 从小到大依次为位Bit.字节Byte.千字节KB.兆M.千兆GB.TB,相邻单位之间都是1024倍,1024为2的10次方,即 1Byte = 8bit,1K = 1024Byte,1M = 1024K,1G = 1024M,1T = 1024G 2.计算机存储元件 寄存器:中央处理器

深入理解Java虚拟机(一)、Java内存区域与内存溢出异常

Java虚拟机所管理的内存包括以下几个运行时数据区: 程序计数器(PCR): 1.是一块较小的内存空间,可以看做是当前线程所执行的字节码的行号指示器 2.为线程私有 3.执行Java方法有PCR,执行native方法时,PCR为空(Undefined) 4.该内存区域不会出现OME(Out Of Memory Exception) Java虚拟机栈: 1.各线程私有,生命周期与线程相同 2.JVMS描述的是Java方法执行的内存模型,局部变量表,操作数栈 3.局部变量表中存储了基本类型,对象,和