美文网首页
[Java]Java的运行时数据区域

[Java]Java的运行时数据区域

作者: DrunkPian0 | 来源:发表于2017-12-07 00:22 被阅读14次

    0x00

    很早之前组里前辈告诉我,对象是存放在堆内存里的,对象的引用是存放在栈内存里的,一直印象很深。今天又在想,static类型的成员变量,是存放在哪里的?会不会造成所在类无法GC导致内存泄露?所以看看书整理一下。


    image.png

    0x01 程序计数器(Counter Register)

    很多年前初学Java的时候,发现子线程跟主线程同时打印1~100,每次程序执行结果都是不同的,这是因为在任何一个确定的时刻,单核CPU都只会执行同一个线程,线程互相抢占CPU资源,感觉好像在异步执行一样。

    因此,为了切换线程后能恢复到正确的执行位置,每条线程都需要一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,称这块区域为“线程私有”的内存。

    不会抛异常。

    0x02 Java虚拟机栈(VM Stack)

    如果把内存分为我们理解的堆内存和栈内存,那栈内存对应的就是Java虚拟机栈,或者说是Java虚拟机栈中的局部变量表部分。
    格外注意「栈帧」也是存放在VM STACK的。看一下我的回答

    局部变量表存放了编译期可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)(我有个疑问,这个基本数据类型难道不应该属于对象的一部分吗,那是不应该存放在Heap中呢。。。)、对象的引用(reference类型,不等同于对象本身,根据不同的虚拟机实现,可能是一个指向对象起始地址的引用指针,也可能是一个代表对象的句柄或者其他与对象相关的位置)和 returnAdress类型(指向下一条字节码指令的地址)。

    会抛StackOverFlow和OutOfMemory异常。

    0x03 本地方法栈(Native Method Stack)

    跟VM Stack类似,只不过这个stack存放本地方法而非Java方法。什么是本地方法

    如果某个虚拟机实现的本地方法接口是使用C连接模型的话,那么它的本地方法栈就是C栈

    会抛StackOverFlow和OutOfMemory异常。

    0x04 Java堆(Heap)

    存放对象实例。


    image.png

    根据Java虚拟机的规范的规定,Java堆可以处在物理不连续的空间,只要逻辑连续就可以,跟磁盘一样。但我有个疑问,既然可以物理不连续,那标记-清除算法造成内存碎片又有什么关系?我猜想是因为,想要在物理不连续的空间分配内存,还需要特殊的算法来记录前一个slot结束位置和后一个slot开始的位置,复杂度仍很高。

    0x05 方法区(Method Area)

    文章开头我的疑问是static类型的成员变量存放在哪儿,答案就是方法区。与Java堆一样,是线程共享的区域,注意栈是不共享的。存储已被VM加载的类信息、常量、静态变量等。它在HotSpot虚拟机上,是等价于永久代(Pernament Gen)的,因为HotSpot把GC分代收集扩展到了方法区,所以HotSpot的GC可以像管理Heap一样管理这部分内存。

    会抛Out Of Memory。

    0x06 运行时常量池

    是方法区的一部分。

    0x07 直接内存

    不是运行时区域的一部分。用于Java和Native缓冲。

    ref:
    https://www.nowcoder.com/questionTerminal/8f393a761e0f4b67b1c442d092eb484d
    http://www.jianshu.com/p/6d1cbe38a54b
    http://blog.csdn.net/zjl477595675/article/details/48101611

    相关文章

      网友评论

          本文标题:[Java]Java的运行时数据区域

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