Java内存分配和程序运行过程
-
Java程序在运行时,需要在内存中分配空间。
-
为了提高运算效率,对空间进行了不同区域的划分
-
每一块区域都有特定的处理数据方式和内存管理方式
1.Java中在内存中分配的空间总共划分为如下几个区域:
栈内存:方法运行时进入的内存,局部变量都存放于这块内存
堆内存:new出来的内容都会进入堆内存,并且会存在地址值
方法区:字节码文件(.class文件)加载时进入的内存
本地方法栈:调用操作系统相关资源
寄存器:交给cpu去使用
程序运行过程详解:
package com.myidea.arrayPackage;
public class TestArray01 { //运行程序先将字节码(class)文件放在放在方法区
public static void main(String[] args) {
/*
因为主方法存放在字节码文件中,所以跟随class进入了方法区,然后main方法会被JVM(虚拟机)自动调入栈内存内执行
*/
int[] arr = new int[3];
/*
此时方法已经进栈,所以数组变量arr跟随方法也进入了栈内存,然后new会在堆内存区域中开辟一块空间,然后这块空间会有自己的一个地址值,new和默认初始化值的长度为3,所以会划分为三个小空间,每个小空间都会有自己的索引和默认初始化值0(数组动态初始化才会有默认初始化值),最后这个地址值会赋值给arr这个数组变量。
定义多个数组时,每个数组都会开辟一个独立的空间。
数组变量记录的地址值可以赋给其他数组,例如:
int[] arr = new int[2]; new关键字在堆内存中开辟一个空间,并将其地址值赋值给arr
int[] aar1= arr; 直接将arr记录的地址值赋值给了arr1
此时两个数组指向堆内存中同一个空间
*/
System.out.println(arr); //arr记录的是地址,所以打印的为地址值
System.out.println(arr[0]); //先通过arr的地址值找到在堆内存中开辟的空间
System.out.println(arr[1]); //然后通过索引找到对应小空间中记录的值
System.out.println(arr[2]); //此时还未赋值,所以打印值数组动态初始化的默认值0
arr[0]=0; //通过arr地址找到在堆内存中开辟的空间,然后通过索引找到对应的小空间
arr[1]=1; //将=后面的值存入索引对应的小空间替换掉空间内存在的值
arr[2]=2;
System.out.println(0); //通过地址找空间,通过索引找位置,打印对应位置的值
System.out.println(1);
System.out.println(2);
}
}
Java内存分配和程序运行过程
-
Java程序在运行时,需要在内存中分配空间。
-
为了提高运算效率,对空间进行了不同区域的划分
-
每一块区域都有特定的处理数据方式和内存管理方式
1.Java中在内存中分配的空间总共划分为如下几个区域:
栈内存:方法运行时进入的内存,局部变量都存放于这块内存
堆内存:new出来的内容都会进入堆内存,并且会存在地址值
方法区:字节码文件(.class文件)加载时进入的内存
本地方法栈:调用操作系统相关资源
寄存器:交给cpu去使用
程序运行过程详解:
package com.myidea.arrayPackage;
public class TestArray01 { //运行程序先将字节码(class)文件放在放在方法区
public static void main(String[] args) {
/*
因为主方法存放在字节码文件中,所以跟随class进入了方法区,然后main方法会被JVM(虚拟机)自动调入栈内存内执行
*/
int[] arr = new int[3];
/*
此时方法已经进栈,所以数组变量arr跟随方法也进入了栈内存,然后new会在堆内存区域中开辟一块空间,然后这块空间会有自己的一个地址值,new和默认初始化值的长度为3,所以会划分为三个小空间,每个小空间都会有自己的索引和默认初始化值0(数组动态初始化才会有默认初始化值),最后这个地址值会赋值给arr这个数组变量。
定义多个数组时,每个数组都会开辟一个独立的空间。
数组变量记录的地址值可以赋给其他数组,例如:
int[] arr = new int[2]; new关键字在堆内存中开辟一个空间,并将其地址值赋值给arr
int[] aar1= arr; 直接将arr记录的地址值赋值给了arr1
此时两个数组指向堆内存中同一个空间
*/
System.out.println(arr); //arr记录的是地址,所以打印的为地址值
System.out.println(arr[0]); //先通过arr的地址值找到在堆内存中开辟的空间
System.out.println(arr[1]); //然后通过索引找到对应小空间中记录的值
System.out.println(arr[2]); //此时还未赋值,所以打印值数组动态初始化的默认值0
arr[0]=0; //通过arr地址找到在堆内存中开辟的空间,然后通过索引找到对应的小空间
arr[1]=1; //将=后面的值存入索引对应的小空间替换掉空间内存在的值
arr[2]=2;
System.out.println(0); //通过地址找空间,通过索引找位置,打印对应位置的值
System.out.println(1);
System.out.println(2);
}
}
2.方法在内存中的调用过程
package com.huly.mypacdage01;
public class methodTest {
/*
第一步,methodTest这个类的字节码文件会加再到方法区,methodTest.class文件中的主方法和其他方法
会随着.class文件一起加载到方法区
*/
public static void main(String[] args) {
//第二步,虚拟机会自动将主方法调入栈内存中执行
method01();
/*
第三步,由于主方法中只有一句程序语句,且是调用方法method01,所以method01方法会被加载到
栈内存中执行
*/
}
public static void method01(){
method02();
/*
第四步,方法1开始执行后,第一个语句又是调用方法2,所以虚拟机会将方法2也调入栈内存中执行,
此时,栈内存中共有主方法、方法1和方法2三个方法,由于方法2中方法体只有一句输出语句,所以执行完打印2的指令后后方法2运行完毕从栈内存中释放,
此时栈内存中还剩两个方法
*/
System.out.println("1");
//第五步,执行输出指令,打印1
method03();
/*
第六步,调用方法3,虚拟机会将方法3调入到栈内存中执行,此时栈内存中的方法又恢复到三个了,方法3开始执行后
输出3,方法3中也只有一个输出语句,打印之后便从栈内存中释放,方法3的内容执行完毕后方法1中也没有程序语句了,
所以方法1也执行完毕从栈内存中释放。又因为主方法中只有调用方法1的语句,所以在方法1执行完毕之后,主方法也执行完毕从内存中释放
*/
}
public static void method02(){
System.out.println(2);
}
public static void method03(){
System.out.println(3);
}
}