对于JVM这块儿的知识,我估计大部分的都是只有在需要面试的时候才会拿出来复习一下,然后就又放下来。也是因为这块儿是 Java
最底层的部分,非常难懂。其实如果真的说认真、细心的去撸一下,了解透彻,应该就不会那么容易忘记。
今天的主要目的也是根据 Oracle
的官方文档来一步一步的理解与学习,并且用用一些 demo
来验证理论。
我们先来看一下JVM的一个架构图:
我们首先看一下官方地址对于运行时数据区域的一个划分: https://docs.oracle.com/javase/specs/jvms/se8/html/index.html
2.5. Run-Time Data Areas
pc
Register 堆存放:对象、数组 (官方证明: 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.)
然后我们看一段代码:
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"); }
其实在这就可以看到,因为有相互调用的情况,这里利用栈的原理(FILO=frist in last out)。
如果一直压栈的话,如果是无穷的递归会怎么办?所以栈是需要规定深度的,对应的就是栈的大小-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. )
堆里面其实可以分为堆与非堆的概念。
方法区、堆的部分属于主内存,所有线程共享,是都可以访问。属于线程不安全。
虚拟机栈、本地方法栈、程序计数器,线程独有/私有,属于线程安全的部分。