JVM深入理解(三)内存模型

背景

对于JVM这块儿的知识,我估计大部分的都是只有在需要面试的时候才会拿出来复习一下,然后就又放下来。也是因为这块儿是 Java 最底层的部分,非常难懂。其实如果真的说认真、细心的去撸一下,了解透彻,应该就不会那么容易忘记。

今天的主要目的也是根据 Oracle 的官方文档来一步一步的理解与学习,并且用用一些 demo 来验证理论。

我们先来看一下JVM的一个架构图:

JVM深入理解(三)内存模型

堆的划分

我们首先看一下官方地址对于运行时数据区域的一个划分: https://docs.oracle.com/javase/specs/jvms/se8/html/index.html

2.5. Run-Time Data Areas

  • 2.5.1. The pc Register
  • 2.5.2. Java Virtual Machine Stacks
  • 2.5.3. Heap
  • 2.5.4. Method Area
  • 2.5.5. Run-Time Constant Pool
  • 2.5.6. Native Method Stacks

堆存放:对象、数组 (官方证明: The heap is the run-time data area from which memory for all class instances and arrays is allocated. )

方法区

方法区存放:静态成员变量、常量、类的信息、常量池 (官方证明: It stores per-class structures such as the run-time constant pool, field and method data, and the code for methods and constructors, including the special methods ( §2.9 ) used in class and instance initialization and interface initialization.)

Java虚拟机栈

然后我们看一段代码

public void a(){
        System.out.println("this is a methd");
        b();
    }

    private void b() {
        System.out.println("this is b methd");
        c();
    }

    private void c() {
        System.out.println("this is c methd");
    }

JVM深入理解(三)内存模型

其实在这就可以看到,因为有相互调用的情况,这里利用栈的原理(FILO=frist in last out)。

  • 先a()入栈发现调用了b(),b()入栈发现调用c();
  • c()执行完毕出栈,然后b()出栈,最后c()方法出栈;

如果一直压栈的话,如果是无穷的递归会怎么办?所以栈是需要规定深度的,对应的就是栈的大小-Xss来控制的,如果是超过大小是会OOM的。

The following exceptional conditions are associated with native method stacks:

StackOverflowError
OutOfMemoryError

本地方法栈

执行本地方法,native方法属于C的方法。 (官方证明:An implementation of the Java Virtual Machine may use conventional stacks, colloquially called "C stacks," to support native methods (methods written in a language other than the Java programming language).)

程序计数器

因为在多线程的情况下,CPU通过轮询来去提高执行效率,线程之间会进行切换。如果从离开到下一次再进来,一定要知道上一次的一个状态。所以它应该是来干这件事情的。

(官方证明:The Java Virtual Machine can support many threads of execution at once (JLS §17). Each Java Virtual Machine thread has its own pc (program counter) register. )

总结

堆里面其实可以分为堆与非堆的概念。

方法区、堆的部分属于主内存,所有线程共享,是都可以访问。属于线程不安全

虚拟机栈、本地方法栈、程序计数器,线程独有/私有,属于线程安全的部分。

参考地址

  • https://docs.oracle.com/javase/specs/jvms/se8/html/index.html
  • https://docs.oracle.com/javase/8/

原文 

http://www.cyblogs.com/jvmshen-ru-li-jie-san-nei-cun-mo-xing/

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » JVM深入理解(三)内存模型

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址