java的内存图

明确:jre jdk jvm关系

(详细去看这篇文章)

三者的大致结构是这样的,简单来说就是JDK包含JRE,JRE又包含JVM的关系。如下图所示:

java的内存图_第1张图片

从图中可以看出JDK是整个JAVA的核心,包括了Java运行环境JRE(Java Runtime Envirnment)、一堆Java开发工具(javac/java/jdb等)和Java基础的类库(即Java API 包)。

java底层内存图

从jdk8开始,java取消了方法区的概念,增加元空间,将原来方法区的功能分给了元空间和堆

下文我还是把元空间称为方法区

java底层用C申请一个大数组,划分为方法区,栈,堆,程序计数器,本地方法栈

  • 方法区:存有类信息,静态信息常量池
  • 栈:方法拷贝运行
  • 堆:对象,字符串常量池
  • 程序计数器:辅助栈区域,决定什么时候出栈入栈。
  • 本地方法区:翻译成操作系统本身的内核方法,对接驱动程序

出现第一个问题:已经有有一个方法区,为什么还要添加一个本地方法区,多此一举??

有时java应用需要与java外面的环境交互,这是本地方法存在的主要原因。

    你可以想想java需要与一些底层系统,如操作系统或某些硬件交换信息时的情况。本地方法正是这样一种交流机制:它为我们提供了一个非常简洁的接口,而且我们无需去了解java应用之外的繁琐的细节,正是有了它才可以通过操作系统驱动硬件。

java运行时本地方法栈也会消耗外面的内存(例如操作系统调用内核方法,消耗外部损失)

补充知识点:

静态成员函数的对象仍然在堆中,句柄在静态信息常量池中

类Person一开始是在硬盘存的,经过jdk变成class文件,调用时再经过jre加入内存

在堆中new一个对象,对象具有对象头(可以找到所属类),对象的成员方法,变量信息。(没有静态信息)

静态信息加载到静态信息常量池

方法只有栈顶的方法在执行

下文是我演示的代码,我将对其进行详细讲解 

package multi_threaded;

public class Test {
    //
    public static void main(String[] mmm) {
        Person x1 = new Person();
        Person x2 = new Person();

        m1(x1,x2);
        System.out.println("x2.age=" +x2.age);
    }
    public static void m1(Person w, Person e) {
        Person m = w;
        w = e;
        e = m;///
        m2(w);
        System.out.println("w.age=" +w.age);
    }
    public static void m2(Person k) {
        k.age = 99;
    }
}
package multi_threaded;

public class Person {
    public int age;
    public String name;
    public static int flag;
    public void m1() {

    }
    public void m2() {

    }
    public static void m3() {

    }
}

编写代码

1.在编写代码的时候是写在硬盘上的,只有被调用后才会进入内存

java的内存图_第2张图片

 当开始加载main方法时入栈

加载Person类和Test类到类信息区,即左上角的部分。

它的静态成员函数和静态方法实体都是在静态信息常量池中。类信息常量池仅仅是存静态成员的地址。

mmm进栈,Test.main栈区先入栈的是mmm,即main函数的参数。

Person对象x1进栈, 在栈区存储的是对象地址,对象开在堆里面。

里面的对象

具有对象头信息(是指得可以找到对象模板的地址,因此可以通过对象.getClass()获取类信息)

具有成员变量:存的是字符串常量地址或数字

具有成员函数 (拷贝)

-----注意,堆里的对象没有静态信息

java的内存图_第3张图片

 x2进栈,操作与x1一,唯一不同的是不用把person再次加载了,只加载一次,静态信息也不用处理

java的内存图_第4张图片

调用m1方法:

调用方法后,方法压栈,

注意:方法并不是含在mian里面的,是压在它头上

java的内存图_第5张图片

 形参person w和e

这个m1(x1,x2)传递的是值传递,所以传过来的是地址

明确:值传递并不是只有数字是值,只要是信息都是值

java的内存图_第6张图片

开始交换操作

m=w

w=e

e=m

java的内存图_第7张图片

 调用m2方法:

形参k指向w,修改年龄为99

java的内存图_第8张图片

 之后递归回去,执行完的出栈,比较简单,此处省略200字。。。

最后运行结果:

java的内存图_第9张图片

w.age=99

x2.age=99

与图中信息一致。讲解完毕,下课! 

你可能感兴趣的:(JavaSE,java,开发语言)