java不同数据(全局变量,局部变量,静态变量,基本数据类型和包装类型)在栈内存和堆内存的存储
全局变量(成员变量),局部变量,静态变量:
全局变量(成员变量):
java变量的数据类型分为两种
1.全局变量定义在类中,在整个类中都可以被访问
2.全局变量有默认的初始化值
3.成员变量随着对象的建⽴⽽建⽴,随着对象的消失⽽消失,存在于对象所在的堆内存中
局部变量:
1.局部变量定义在局部范围内:如⽅法,函数,语句中,只在作⽤域有效
2.局部变量没有默认初始化值
3.局部变量存在于栈内存中,作⽤的范围结束,变量空间会⾃动释放
静态变量:
⽤static关键字修饰的变量,被所有对象所共享
成员变量与静态变量的区别:
1.声命周期不同
成员变量随对象创建⽽创建,随对象销毁⽽销毁
静态变量随类加载⽽加载,随类消失⽽消失
2.调⽤⽅式不同
成员变量只能被对象调⽤
静态变量可以被对象调⽤,也可以被类名调⽤
3、别名不同
成员变量也称为实例变量。
静态变量也称为类变量。
4、数据存储位置不同
成员变量存储在堆内存的对象中,所以也叫对象的特有数据。
静态变量数据存储在⽅法区(共享数据区)的静态区,所以也叫对象的共享数据。
列表对⽐:
成员变量、局部变量、静态变量的区别
成员变量局部变量静态变量
定义位置 在类中,⽅法外⽅法中,或者⽅法的形式参数在类中,⽅法外
初始化值有默认初始化值⽆,先定义,赋值后才能使⽤有默认初始化值
调⽤⽅式对象调⽤---对象调⽤,类名调⽤
存储位置堆中栈中⽅法区
⽣命周期与对象共存亡与⽅法共存亡与类共存亡
别名实例变量---类变量
基本数据类型(8个):
int,byte,char,short,float,double,long,boolean
包装类数据(8个):
Integer,Byte,Character,Short,Float,Double,Long,Boolean
java中的数据存储:
1. 寄存器(register)。 这是最快的存储区,因为它位于不同于其他存储区的地⽅——处理器内部。但是寄存器的数量极其有限,所以寄存器由编译器根据需求进⾏分配。你不能直接控制,也不能在程序中感觉到寄存器存在的任何迹象。
------最快的存储区, 由编译器根据需求进⾏分配,我们在程序中⽆法控制.
2. 堆栈(stack)。位于通⽤RAM中,但通过它的“堆栈指针”可以从处理器哪⾥获得⽀持。堆栈指针若向下移动,则分配新的内存;若向上移动,则释放那些 内存。这是⼀种快速有效的分配存储⽅法,仅次于
寄存器。创建程序时候,JAVA编译器必须知道存储在堆栈内所有数据的确切⼤⼩和⽣命周期,因为它必须⽣成 相应的代码,以便上下移动堆栈指针。这⼀约束限制了程序的灵活性,所以虽然某些JAVA数据存储在堆栈中——特别是对象引⽤,但是JAVA对象不存储其 中。
------存放基本类型的变量数据和对象,数组的引⽤,但对象本⾝不存放在栈中,⽽是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池中)
3. 堆(heap)。⼀种通⽤性的内存池(也存在于RAM中),⽤于存放所以的JAVA对象。堆不同于堆栈的好处是:编译器不需要知道要从堆⾥分配多少存储区 域,也不必知道存储的数据在堆⾥存活多长时间。因此,在堆⾥分配存储有很⼤的灵活性。当你需要创建⼀个对象的时候,只需要new写⼀⾏简单的代码,当执⾏ 这⾏代码时,会⾃动在堆⾥进⾏存储分配。当然,为这种灵活性必须要付出相应的代码。⽤堆进⾏存储分配⽐⽤堆栈进⾏存储存储需要更多的时间。
------存放所有new出来的对象。
4. 静态存储(static storage)。这⾥的“静态”是指“在固定的位置”。静态存储⾥存放程序运⾏时⼀直存在的数据。你可⽤关键字static来标识⼀个对象的特定元素是静态的,但JAVA对象本⾝从来不会存放在静态存储空间⾥。
------存放静态成员(static定义的)
5. 常量存储(constant storage)。常量值通常直接存放在程序代码内部,这样做是安全的,因为它们永远不会被改变。有时,在嵌⼊式系统中,常量本⾝会和其他部分分割离开,所以在这种情况下,可以选择将其放在ROM中
------存放字符串常量和基本类型常量(public static final)
6. ⾮RAM存储。如果数据完全存活于程序之外,那么它可以不受程序的任何控制,在程序没有运⾏时也可以存在。
------硬盘等永久存储空间 就速度来说,有如下关系:
寄存器 >堆栈 > 堆 > 其它
这⾥我们主要关⼼栈,堆和常量池,对于栈和常量池中的对象可以共享,对于堆中的对象不可以共享。
栈中的数据⼤⼩和⽣命周期是可以确定的,当没有引⽤指向数据时,这个数据就会消失。堆中的对象的由垃圾回收器负责回收,因此⼤⼩和⽣命周期不需要确定,具有很⼤的灵活性。
栈内存:
某⼀个函数被调⽤时,这个函数会在栈内存⾥⾯申请⼀⽚空间,以后在这个函数内部定义的变量,都会分配到这个函数所申请到的栈。当函数运⾏结束时,分配给函数的栈空间被收回,在这个函数中被定义的变量也随之被释放和消失。栈内存⽐堆内存⼩得多
堆内存:
通过new产⽣的数组和对象分配在堆内存中。堆内存中分配的内存,由JVM提供的GC(机制)来管理。在堆内存中产⽣了⼀个数组对象后,我们还可以在栈中定义⼀个变量,这个栈中变量的取值等于堆中对象的⾸地址。栈内存中的变量就成了堆内存中数组或者对象的。我们以后就可以在程序中直接使⽤栈中的这个变量来访问我们在堆中分配的数组或者对象,相当于数组或者对象起的⼀个别名,或者代号。
是⼀个普通的变量,定义时在栈中分配;引⽤变量在被运⾏到它的作⽤域之外时就被释放,⽽我们的数组和对象本⾝是在堆中分配的,即使程序运⾏到使⽤new产⽣对象的语句所在的函数或者代码之后,我们刚才被产⽣的数组和对象也不会被释放。数组和对象只是在没有引⽤变量指向它,也就是没有任何引⽤变量的值等于它的⾸地址,它才会变成垃圾不会被使⽤,但是它占据着内存空间不放(这也就是我们Java⽐较吃内存的⼀个原因),在随后⼀个不确定的时间被器收⾛。
堆内存和栈内存的区别
1、应⽤程序所有的部分都使⽤堆内存,然后栈内存通过⼀个线程运⾏来使⽤。
2、不论对象什么时候创建,他都会存储在堆内存中,栈内存包含它的引⽤。栈内存只包含原始值变量好和堆中对象变量的引⽤。
3、存储在堆中的对象是全局可以被访问的,然⽽栈内存不能被其他线程所访问。
4、栈中的内存管理使⽤LIFO的⽅式完成,⽽堆内存的管理要更复杂了,因为它是全局被访问的。堆内存被分为,年轻⼀代,⽼⼀代等等(Young Generation and Old Generation.)。
5、栈内存是⽣命周期很短的,然⽽堆内存的⽣命周期从程序的运⾏开始到运⾏结束。
6、我们可以使⽤-Xms和-Xmx JVM选项定义开始的⼤⼩和堆内存的最⼤值,我们可以使⽤-Xss定义栈的⼤⼩
7、当栈内存满的时候,Java抛出java.lang.StackOverFlowError异常⽽堆内存满的时候抛出java.lang.OutOfMemoryError: Java Heap Space错误
8、和堆内存⽐,栈内存要⼩的多,因为明确使⽤了内存分配规则(LIFO),和堆内存相⽐栈内存⾮常快。
例(引⽤):
String 类型的变量通常有两种赋值⽅式:⼀种直接赋值,例如String a = "hello world";另⼀种是⽤构造⽅法,例如 String b = new String ("hello world");那么这⾥的a 和b是否相等呢?他们⼜有什么不同 呢?
如果⽤=作⽐较,则它们不相等,因为“=”⽐较的是基本数据类型的值是否相等或者⽐较对象是否为同⼀个对象;⽽变量a和变量b指向的是两个不同的对象,为什么这么说呢?先来理解⼀下2个变量的赋值过程,对于表达式String a = "hello world",会先创建⼀个字符串对象“hello world”,⽽这个字符串实际上是放在字符串缓冲区中,然后把a指向这个对象;⽽对于String b = new String("hello world");则会创建两个对象⼀个是“hello world”这个放在字符串缓冲区中的,另⼀个是new ⽅法构造出来的对象new String() 这个对象,新对象中保存的是“hello world”对象罢了,这个对象是放在堆内存中,⽽b 指向这个new String ()对象,这显然是不同的两个对象,所以他们⽤ “=”⽐较的结果为false。
如果⽤equals()⽅法⽐较,这结果为true,因为equals()⽅法⽐较的是对象的内容,它们的内容都为“hello world”。
另外值得提醒的是,字符串缓冲区中对相同的字符串只会存⼀次。假如我们同时写了String a ="hello world";String b = new
String("hello world");那么字符串缓冲区实际只有⼀个hello world 字符串,在给b赋值时,会先检查字符
串缓冲区中是否有“hello world”这个字符串,如果有则不创建,直接new String(),然后赋值,因此这种情况下,表达式String  b= new String ("hello world")也只创建了⼀个对象。
总结:
栈内存:局部变量,对象的引⽤,基本数据类型
堆内存:全局变量,包装类,对象;
有不对的地⽅⿇烦指出

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。