一、java内存
任何程序想要运行,都需要向windows申请内存,java将申请的内存分为五部分:
- 栈(Stack):
a. 存放方法中的局部变量
b. 局部变量: 方法的参数,或者方法体{}中的变量
c. 作用域:一旦超出作用域,立刻从栈内存中消失
- 堆(Heap):
a. 凡是new出来的东西,都存放在堆内存中
b. 堆内存中的东西都有一个十六进制的地址
c. 堆内存中的数据都有默认值,规则如下:
整数:0
浮点数:0.0
字符型:\u0000
布尔型:false
引用型:null
- 方法区(Method Area):
a. 存储.class相关信息,包含方法的信息,但方法运行在栈内存中
- 本地方法栈(Native Method Stack):
a. 与操作系统相关
- 寄存器(pc Register):
a. 与CPU相关
二、单个数组的内存
一)、图解

二)、详解
- 方法区中存储了程序的main()方法
- 但运行main()方法,需要进栈
- 而后发现,程序运行需要
new一个数组,new的数组存放在堆内存中 - 栈内存中的数组仅仅是存放在堆内存中的地址值
- 之后栈中对数组值的修改,都是通过地址值,在堆内存中进行修改。
三、 两数组指向同一地址内存图解
一)、图解

二)、 详解
- 两个数组指向同一个地址,任何一个数组进行修改操作,都会使得堆内存中存储的数组值改变。
四、对象的内存情况
一)、图解

二)、详解
- 首先执行方法区中的main()方法,将
main()方法压入到栈中,可以形象地理解为将main()方法压栈到底部; - 创建
Phone类的对象,在堆内存中创建Phone对象,对象地址给到栈,注意此时堆内存中对象的成员变量根据方法区中的成员变量创建了,但堆内存中并未加载对象的成员方法,而是通过地址指向了方法区中该对象自身对应类的成员方法,即此时:栈中的对象通过地址指向堆中的对象,而堆中的对象的成员变量是存于此处的,但成员方法是通过地址指向方法区的类对应的成员方法; main()方法继续执行,需要执行对象的call()成员方法,于是找到堆,堆通过成员方法的地址找到方法区中的成员方法,将该方法压栈到栈中执行,执行完成后,弹栈消失,继续执行main()中之后的语句,直到main()执行完成, 在栈中弹栈消失。
五、static的内存情况
一)、图解

二)、详解
- 方法区中存在静态区,存储静态成员变量或静态成员方法
六、继承的内存情况
一)、图解

二)、详解
- 从方法区开始,到
main()方法弹栈消失为止
七、 线程的内存图解
一)、图解

二)、详解
MyThread extends Thread,重写其run()方法- 创建
MyThread对象,执行start()方法 - 直接调用
run()方法不会开辟新的栈内存空间