JVM内存划分
1、在Java运行的时候 JVM虚拟机拿到自己能支配的内存 将内存进行分割 2、本地方法栈存储是C++ native方法 3、程序计数器指向程序当前运行的位置 4、方法区存储元数据信息 在jdk1.7之前 叫做永久代 jdk8之后改为元数据空间 主要存储一些静态方法或变量 类加载classloader等等这样一些全局的信息 5、栈区存储函数当前运行中的临时变量 栈、本地方法栈、程序计算器是线程私有的 每个线程在运行的过程中 会单独分配内存 有多少线程就会有多少栈区 6、堆区和方法区都是全局共享 堆区主要用来存对象 7、栈区存储的是对象的引用类型 只是对象的一个地址 最终指向堆区实际存在的对象
举例说明
示例1
java程序代码
结果为20,10
示意图
1、执行main函数 在栈中给a变量分配栈内存 赋值10(a是实参数) 2、执行func1 在栈中给a变量分配栈内存 赋值10(a变成了形参) 3、在栈中给b变量分配栈内存 赋值10 4、修改a值为11 5、执行完func1释放栈内存 栈遵循先入后除原则 先删除b再删除a
示例二
1、执行func1在栈中分配内存给变量a并赋值10 占4个字节大小 2、在栈中分配内存给变量b并赋值10 占4个字节大 3、在堆中创建一个对象new Person id默认为0 ,name默认为null 4、在栈中分配内存给变量p表示指向对象的地址 地址是int类型 占4个字节大 是引用类型 5、通过p指针给堆中的对象的属性id赋值为1 6、在堆中创建一个String对象 该对象中有char数组 char数组是值类型 不是一个对象类型 7、p指针给堆中的对象的属性name 它也代表一个指针 指向String对象 8、func1执行完释放圈红部分内存 栈上12字节的内存就会被释放 9、堆中的对象如何释放? 在堆上运行的对象不能随着函数运行完毕自动清理 你也不知道是否有其他线程也引用当前对象 是否也是引用的当前这个地址来访问的
Java的基础数据类型都是值类型 指针也是值类型 因而是直接存到内存 不是存地址去寻址
1、main函数在方法区 2、如果类Main中有一个static Integer a 静态全局变量 那么该变量会存放在方法区中 所有的栈函数都可以Main.a引用