• <<深入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虚拟机采用的是直接指针访问方式进行对象的访问。

  • 相关阅读:
    于丹关于人性的总结
    Oracle中的MS SQLSERVER@@ERROR
    分享2011年10月网上随机搜集的超酷超有趣的web开发和Javascript代码
    来自Nike Better World的视差滚动(Parallax Scrolling)特效 分享一些教程和灵感
    2011年最新使用CSS3实现各种独特悬浮效果的教程
    分享2011年50个最棒的wordpress主题 第一部分
    分享2011年50个最棒的wordpress主题
    分享一个超酷创建互动文档的Javascript类库 tangle
    jQuery Howto: 如何快速创建一个AJAX的"加载"的图片效果
    什么时候我们该选择VPS服务器?
  • 原文地址:https://www.cnblogs.com/lylife/p/5493271.html
Copyright © 2020-2023  润新知