JVM内存模型(1)、运行时数据区域

作者: 编程界的小学生 | 来源:发表于2017-09-06 14:03 被阅读58次

    一、概括图

    Paste_Image.png

    只是一张概括图,但是这里面的知识点足够了。其实栈内存的虚拟机栈和本地方法栈还包含栈帧等一些东西,这里不作讲解是因为他不属于我们这篇幅的内容,堆内存中的新生代和老年代两块区域这里也不做讲解,这些东西以后的篇幅中一定会做透彻的讲解!!

    二、概念解读

    2.1、程序计数器(Program Counter Register)
    这个概念不多说,直接看我这篇文章,通俗易懂。看了后不可能不懂!!!!
    http://www.jianshu.com/p/005abe4a9bff

    2.2、Java虚拟机栈(Java Virtual Machine Stacks)
    上面说了,栈还包含栈帧等一些内容。
    每个方法在执行的时候都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态连接、方法出口等信息。每个方法从被调用到执行完,都对应着一个栈帧在虚拟机栈中入栈到出栈的过程。

    Paste_Image.png

    这里只讲解局部变量表,还是那句话,下面的东西以后都会详细讲。

    局部变量表存放了编译期间可知的八大基本数据类型、对象引用和returnAddress类型(指向了一条字节码指令的地址)。

    其中double和long类型的数据会占用2个局部变量空间(Slot),其余的数据类型只占用1个。

    局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在栈帧中分配多大的局部变量空间是完全确定的,在方法运行期间是不会改变局部变量表大小的。

    我说到这里,想必有经验的程序员都会大彻大悟一件事:就是我这里无形透露出一个JVM优化来,为什么入参都用Object实体去接收,而不用多个参数? 这就是因为你一个实体去接收的话,我不管你实体里面几个参数,我这个实体的引用在局部变量表里只占用1个Slot(局部变量空间)。所以我建议,如果只有1个非double和long类型的参数,直接写参数就行了,相反的话就用Object接收,这样的性能是最优的。

    2.3、本地方法栈(Native Method Stack)
    与Java虚拟机栈作用非常相似,唯一不同的是本地方法栈是执行Native方法。而不是执行Java方法。比如String类里面的public native String intern();

    2.4、Java堆(Java Heap)
    Java堆几乎是Java虚拟机所管理的内存中最大的一块区域。此内存区域的唯一目的就是存放对象实例。简言之:所有的对象实例以及数组都要在堆上分配(有一种情况是对象逃逸,这种情况不在堆上,目前不考虑,以后会讲)。
    Java堆也是垃圾收集的主要区域。

    2.5、方法区(Method Area)
    也称之为:永久带。用于存储已被虚拟机加载的类信息、常量、静态变量、即时便器编译后的代码等数据。

    2.6、运行时常量池(Runtime Constant Pool)
    是方法区的一部分。存放常量,比如String str = "abcd";;此时abcd就是存放到此区域,再比如final修饰的常量也会放到此区域。

    2.7、直接内存(Direct Memory)
    直接内存并不是虚拟机运行时数据区的一部分。本机直接内存就是电脑内存条大小。

    3、什么是线程私有的?
    不难发现我们第一张图上,有线程私有的空间,也有线程共有的空间。
    线程私有的空间是线程独有的,会随线程而生,也会随线程结束而灭亡,且这块空间是自己独有,其他线程不可入侵的。

    4、注意
    不难发现我讲了一堆概念,但是每个知识点我都用简单的两三句话概括了,目的就是为了怕看起来抓不住重点。现在看不懂这些概念没事,但是一定要混个眼熟,因为后面我会用真实的案例去讲解。到那时候你会对这些概念大彻大悟,此篇幅要求掌握每个区域是干嘛的,放了哪些东西进去即可。虽然都是抽象的概念,但是他真的很主要!!!!

    若有兴趣,欢迎来加入群,【Java初学者学习交流群】:458430385,此群有Java开发人员、UI设计人员和前端工程师。有问必答,共同探讨学习,一起进步!
    欢迎关注我的微信公众号【Java码农社区】,会定时推送各种干货:


    qrcode_for_gh_577b64e73701_258.jpg

    相关文章

      网友评论

      • 刘志磊LJ:楼主,有一个问题请教一下,您上面说除了long和double,局部变量表上的其他类型都占用32位。看到这我有翻了翻周志明的虚拟机那本事,那上面说的是对于对象引用类型,虚拟机规范并没有规定其大小,所以我觉得您说的定义成一个实体进行传递可以优化 我有点疑问:joy:
        编程界的小学生:@刘志磊LJ 除了double和long类型,其余都只占用1个slot

      本文标题:JVM内存模型(1)、运行时数据区域

      本文链接:https://www.haomeiwen.com/subject/ceemjxtx.html