Java学习之内存解析

一、内存

1. 栈内存(Stack)

  • 存放的都是方法中的局部变量,一旦超出作用域,就会从栈内存中消失
  • 方法运行是在栈当中

2. 堆(Heap)内存

  • 凡是new出来的,都在堆内存中
  • 堆内存的中的数据都有地址值(16进制)
  • 堆内存的数据都有默认值

3. 方法区(Method Area)

  • 存储.class相关信息,包含方法的信息,比如成员变量,成员方法,main()方法
  • 该区域只是包含了方法的死信息,真正的运行是在栈内存当中

4. 本地方法栈(Native Method Stack)

  • 与操作系统相关

5. 寄存器(pc Register)

  • 与CPU相关

二、成员变量与成员方法内存解析

1. 执行内存图

Java学习之内存解析

2. 内存解析

  • 在运行main()方法之前,方法区最先有数据,方法区存储.class的相关数据,也就是Phone.class和Demo1PhoneOne.class中的成员变量和成员方法
  • 当执行main()方法时,main()方法首先进栈开始执行
  • new Phone()存储在堆内存中,当执行该行代码时,堆内存会从方法区中获取Phone.class的相关数据,此时堆内存中就存储了成员变量对应的变量值、以及成员方法对应在方法区的地址值
  • 当将new Phone()赋值给左边的变量时,就是将new Phone()在堆内存中的地址值赋值给了栈内存中的对象
  • 当代码为成员变量赋值的时候,实际上是通过栈内存中Phone()的地址值找到堆内存中的成员变量,进而进行的赋值
  • 当代码调用成员方法时,首先通过栈内存中Phone()的地址值找到堆内存中成员方法的地址值,再通过成员方法的地址值找到方法区中的成员方法,找到后,该成员方法进栈执行,执行完成之后,会立刻从栈内存中消失,也就是出栈
  • 当所有方法执行完之后,main()方法结束,此时main()方法也会从内存中消失,代码结束

三、static

1. 动态与静态

  • 动态是指Java程序在JVM上运行时,JVM会根据程序的需要,创建对象并为对象分配内存,对象使命结束后,会被垃圾回收器销毁,内存回收由JVM统一管理并分配给其他新创建的对象
  • 静态是指Java程序还没有运行时,JVM就会为加载的类分配空间,并存储被static关键字修饰的内容;如静态成员变量,Java类加载到JVM中,JVM会把类以及类的静态成员变量存储在方法区,方法区是线程共享且很少发生垃圾回收的区域,所以被static关键字修饰的内容都是全局共享的,且只会为其分配一次存储空间

2. 执行内存图

Java学习之内存解析

3. 内存解析

  • 在方法区中,有一块独立的空间叫静态区,专门用于存储静态static数据
  • 上述代码中Student.room是通过类名来调用static修饰的成员变量,那么此时,栈内存中的Student.room代码将不会再去堆内存中得到成员变量的值,而是直接去方法区中找到该成员变量,进而再去静态区中得到该成员变量的值
  • 注意:根据类名称访问静态成员变量的时候,全程和对象就没关系,只和类有关系