虚拟机中数据的那些事儿

一.虚拟机的数据域

  虚拟机的运行时数据域组成:程序计数器,虚拟机栈,本地方法栈,堆,方法区,运行时常量池(方法区的一部分)

    1.线程隔离部分:虚拟机栈,本地方法栈,程序计数器

    2.线程共享:方法区,堆

    

  

  程序计数器:当前线程的所执行字节码的行号指示器。(各种分支,循环,跳转等都是由当前线程的程序计数器完成)。

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

        方法,这个计数器为空(undefined),唯一一个没有规定OutOfMemoryError的区域。

  虚拟机栈:1.生命周期与当前线程相同(线程私有)。

       2.描述的是Java的内存模型:每个方法被执行的时候都会创建一个栈帧,用于保存局部变量表,操作栈,动态链接,

        方法出口等信息。每一个方法被调用知道执行完成的过程,对应着一个栈帧从入栈到出栈的过程。

       3.局部变量表包含这个各种基本的数据类型,还有对象的引用(指针,句柄,字节码指令的地址)。

       4.如果当前线程的虚拟机栈满了(例如递归层数太深)那就会抛出StackOverFlowError,可以动态扩充栈的大小,

        但是如果扩充也无法申请到足够的内存,这个时候会抛出OutOfMemoryError。

  本地方法栈:这个是实现Native方法的服务。自由度很高,本地方法栈中使用的那些语言或者数据结构没有强制规定,也会抛出

        OutOfMemoryError或者StackOverFlowError异常。

  Java堆:1.存放对象实例,几乎所有对象实例都存在堆中分配内存。

      2.是垃圾收集器的主要区域(GC堆)

      3.内存中的是不连续的,可扩展的。

      4.堆还可以细分为新生代与老年代,还可以分为:Eden:From Survivor:To Survivor;8:1:1。

      5.为了更好的管理以及回收内存:Java堆中还可能划分出多个线程私有的分配缓冲区(Thread Local Allocation Buffer,TLAB)。

  方法区:1.用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。(Non-Heap)大伙们说的永久代。

      2.自由度很高啊,内存可以选择固定或者可扩展,还可以不实现垃圾收集。

      3.永久代也不是一定永远存在的,这个区域的回收目的主要是对常量池的回收和对类型的卸载,条件苛刻啊,但是回收还是有必要。

      4.同样的,无法满足内存分配的需求时,会抛出OutOfMemoryError。

  运行时常量池:存放编译期间生成的各种字面量和符号引用,类加载后存放到运行时常量池中。而且具有动态性,不一定是编译期间生成常量

      运行期间也可以将常量放到常量池中。

  直接内存:1.可能导致OutOfMemoryError

       2.JDK1.4中加入的NIO基于通道与缓冲区的IO方式

       3.通过Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。(能提高性能,避免在Java堆与Native堆中来回复制数据)。

       4.这个内存大小也是会受到本机总内存的影响,RAM和SWAP交换区。

二.对象的访问方式

  场景:Object obj = new Object();新建的一个对象。

   分析:obj中的信息(类信息,父类,方法,接口等)都会在Java堆中呈现。在虚拟机栈中,这个会成为一个reference(引用类型)

      出现在本地变量表中。

   问题:虚拟机栈中的reference是如何定位到Java堆中的?

   方法:1.使用句柄

      Java堆中有一小块内存是作为句柄池,reference指向的就是对象句柄的地址。句柄存放就是对象实例数据和类型数据(方法区)

      

           2.使用指针

           

   两种方法的优缺点:

      句柄的好处就是,reference存放的是稳定的句柄地址,在对象移动的时候(GC收集常做的事),就只是需要改变句柄的实例指针即可。

      指针的好处:就是快,比句柄少了一次指针的访问。(Sun HotSpot就是使用指针)。

 

   总结:主要介绍了虚拟机的数据区域情况和对象的访问方式,这个是学习虚拟机最主要掌握的根本

   参考:深入理解java虚拟机(神书java开发必读啊)

 

       

  

 

 

  

posted @ 2018-06-18 23:03  肥仔中意编程  阅读(332)  评论(0编辑  收藏  举报