方法区、堆、栈
Java的Jvm内存可分为3个区:堆(heap),栈(stack),方法区(method)
-
java数据类型:
基础数据类型:boolean、byte、short、char、int、long、float、double
引用数据类型:类、接口、数组 -
堆区(heap):
-
提供所有类实例和数组对象的存储区域
-
jvm,只有一个堆区(heap)被所有线程共享,堆中不存放基本数据类型和引用,存放new创建的对象以及数组。
eg:构造器new出来的实例 User user = new User(); user是实例,会放入栈区(stack) User才是对象本身,会放入堆中(heap)
- 堆栈(stack):
-
每个线程都有一个栈区、栈中只保存基础数据类型的对象和自定义对象的引用(不是对象本身),对象都存放在堆区中。
-
每个栈中的数据(原始类型和对象引用)都是私有的,其它栈不能访问。
eg:int b= 1; b为基本数据类型之一,放至栈区 eg:构造器new出来的对象实例 User user = new User(); user亦是User的引用
- 方法区(method)
-
又叫静态区与堆区一样,被所有线程共享。静态区包含了所有的Class与Static对象。
-
方法区中包含的都是在整个程序中永远唯一的对象,如,Class与Static变量。
-
运行时,常量池都分配在Java虚拟机的方法区当中。
常量池,只是维护了一个已加载类的常量
注意:1)变量(即八大基本类型变量),在栈中直接保存它所对应的值
2)而引用类型的变量保存的是一个指向堆区的指针,通过这个指针就可以找到这个实例在堆区对应的对象。
3)所以,普通类型变量只在栈区中占用一块内存,
而引用类型变量则要在堆区和栈区都占用一块内存,只不过,在堆区保存的是该变量的值,而在栈区则是保存了一个指向堆区值的指针
总结:
1.分清什么是实例什么是对象。
Class a= new Class();此时a叫实例,而不能说a是对象。
实例在栈中,对象在堆中,操作实例实际上是通过实例的指针间接操作对象。多个实例可以指向同一个对象。
2.栈中的数据和堆中的数据销毁并不是同步的。
方法一旦结束,栈中的局部变量立即销毁,但是堆中对象不一定销毁。
因为可能有其他变量也指向了这个对象,直到栈中没有变量指向堆中的对象时,它才销毁,而且还不是马上销毁,要等垃圾回收扫描时才可以被销毁。
3.以上的栈、堆、代码段、数据段等等都是相对于应用程序而言的。
每一个应用程序都对应唯一的一个JVM实例,每一个JVM实例都有自己的内存区域,互不影响。并且这些内存区域是所有线程共享的。这里提到的栈和堆都是整体上的概念,这些堆栈还可以细分。
4.类的成员变量在不同对象中各不相同,都有自己的存储空间(成员变量在堆中的对象中)。而类的方法却是该类的所有对象共享的,只有一套,对象使用方法的时候方法才被压入栈,方法不使用则不占用内存。
其它补充知识
- 堆区:FIFO队列,先进先出 。JVM只有一个堆区,被所有线程所共享。堆存,放在二级缓存当中,调用对象的速度相对慢一点,生命周期,有虚拟机的垃圾回收机制决定
2.栈区,FILO队列,先进后出,暂存数据的地方。每个线程都包含一个栈区。栈存放在一级缓存当中,存取速度快,“栈是限定仅在表头进行插入和删除操作的线性表”
EG:画图:手枪弹夹 装进去 以及 打出去
emmmm~~~小编,着实不是绘图大佬 将就下下饭吧hhhhhhhhhhhh
上面,左边表示装子弹,1是最先装进去的,那么,打出去,也是最后面打出去。
说在最后,欢迎大佬的指点。