目录
1.JVM虚拟机,在Java执行中拿到了自己能够支配的内存后,分为了五个区域:
1.JVM虚拟机,在Java执行中拿到了自己能够支配的内存后,分为了五个区域:
栈区,堆区,本地方法栈,方法区,程序计数区
(1)简要分析
本地方法栈:
存储c++的native方法
程序计数器:
指向当前程序运行的位置
方法区:
存储一些元数据信心,jdk7之前又叫永久代,Jdk8改了,存static静态变量,累加器classloader等等全局的信息。
栈区:
用于存储当前运行的函数中的临时变量等等,和c++类似,进栈出栈。
线程私有:
栈区、 本地方法栈、程序计数器是线程私有的,也就是说,每个线程在运行中都会,分别创建自己的这一份内存(栈区、 本地方法栈、程序计数器),那就说明有多少个线程就有多少个栈区。而堆区和方法区是全局共享的。
堆区:
用于存对象的。那我们之前说栈区里也有变量,那肯定也有对象,这矛盾吗?并不矛盾,栈区里存的那是对象的引用即地址,指向实际存在堆区里面的对象。然后下面这篇文章还不错,看看。Java中基本数据类型和引用数据类型的存放位置_roon9527的博客-CSDN博客_java基本数据类型存储在哪里
(2)举例
例1
删除时也是后入先出,先删除b再删除a。但是main函数运行结果是20,10这是为什么呢?
20是func1里面打印的没问题,至于最后main里面a还是10:
这里是传值,所以func1栈区里面啊,自己有一个不同于main栈里面的a(形参),改的也是这个,并且最后还都被删了,所以留下的依旧是main栈里面的a。
例2
p是引用类型,类似于指针,是个占4个字节的地址。id=1就是等于1.
重点在于这个string的赋值,你也可以回忆自己的笔记,这样直接赋值不new,会以字符串常量的形式存在方法区的常量池(有一个存字符串的串池)中,而如果想开辟一个空间,按一般引用操作的话,那得改成p.name = new String("liming")才对,此时堆里面会这样:
然后结束清空,也很重要:
首先栈里面的东西直接拿掉,这没问题,但是堆里东西怎么办呢?那就要用到GC了。
堆上创建的对象不能随着函数运行完毕而自动清理的,因为我们也不知道是不是有其他地方还用到了这些对象。GC在下一篇笔记专门做。
例3:
这很简单,传引用不会创建副本,地址指向Main的p2,肯定直接就是改堆里面的。