说到java的堆和栈就想起来了,java内存中的分配结构。作为一个Java的程序员,我们肯定知道Java的程序是运行在java虚拟机上的,也就是平时所说的JVM。程序中所有的方法、变量、常量、实例、静态存储都是由JVM在内存中进行分配的。
1. 寄存器:JVM中运行最快的,JVM内部的虚拟的存储器和CPU有关,我们无法控制。
2. 堆栈(也就是平时所说的栈stack):用来存放基本数据类型和引用数据类型的实例的(也就是实例对象的在堆中的首地址,Person p = new Person; p存贮在堆栈中,值为@23651dff。还有就是堆栈是线程独享的。每一个线程都有自己的线程栈。
3. 堆(也叫做对内存或者对空间deap):用来存放程序动态生成的数据。(new 出来的对象的实例存储在堆中,但是仅仅存储的是成员变量,也就是平时所说的实例变量,成员变量的值则存储在常量池中。成员方法是此类所实现实例共享的,并不是每一次new 都会创建成员方法。成员方法被存储在方法区,并不是存储在第一个创建的对象中,因为那样的话,第一个对象被回收,后面创建的对象也就没有方法引用了。静态变量也存储在方法区中。局部变量在栈内存中,JVM为每一个类分配一个栈帧,然后引用类型的局部变量指向堆内存中的地址),堆是内存中共享的区域,要考虑线程安全的问题。
4. 方法区(non-deap,(非堆),在堆中为其分配的一部分内存):里面存储的是一些。类类型加载的东西(也就是反射中的.class之后的Class),用于存储已经被虚拟机加载的类的信息、常量、静态变量等。与堆一样,是被线程共享的内存区域,要注意线程安全问题。
5. 常量池:上面已经说了,存储在堆中的。JVM会对每一个加载的类维护一个常量池。用于存储成员变量中的数值。(String str= “aa”, aa也是存储在String.class类中的常量池中的。Str只是在栈中作为aa的首地址)
6. 代码段:这个就是用来存储代码片段的
7. 数据段:这个是用来存储静态成员的,包括静态变量,静态常量(存储在这里面的常量池当中),静态方法,静态类。
**下面就是java内存中的分配情况
里面还少一个方法区,存储在堆中。
※ 说完JVM中的内存分配,我们来说一说堆和栈之间的区别。
1.堆
·存放new之后的实例
·每一个变量都有默认值(char:’/u0000’)
·生命周期未知,存储顺序未知。JVM有垃圾回收系统,GC会根据4种(强、软、弱、虚)引用进行不同程度的回收。
2.栈
·栈中存放的是基本数据类型和存放类对象的引用
·栈中的存放是有顺序的,而且JVM分配的空间是固定的,不能改变。这样使栈失去了灵活性。当局部变量使用完之后,JVM就会进行清除(也就是出栈)。
※接下来使用一个小例子来对堆栈进行更深一步的了解
例子:
String str = “a”;
String strr = “bc”;
String str1 = “abc”; //定义字符串变量str1
Stringstr2 = “abc”; //定义字符串变量str2
Stringstr3 = new String(“abc”); //以new的方式定义字符串变量str3
Stringstr4 = new String(“abc”);//以new的方式定义字符串变量str4
String str5 = str + strr;
String str6 = “a” + “bc”;
结果:
* str1 ==str2 true; ①
* str2 ==str3 false; ②
* str3 ==str4 false; ③
*str1 == str5 false; ④
*str1.equals(str5) true; ⑤
*str1==str6 true; ⑥
讲解:
·‘==’比较的是地址
Str1 和 str2显然指向的是String中常量池中的一个地址。(何灵鸿上次发的String的两种创建方式)
·equals比较的是内容
① 由于地址相同,所以true
② 由于str3 使用的new ,相当于在String类堆中创建了一个堆地址。而str2的地址则是在常量池中。地址对不上,因此false
③ 和②的原理是一样的,相当于new了两个对象,也就是各自拥有了自己的地址。因此false。
④ str5使用的是字符串变量的相加。当看String的源码的时候,你会发现str.append()方法。本质上是先new 一个Stringbuilder对象,然后使用这个对象进行append,最后Builder对象toStirng回到String类型。也就是地址发生了变化。
结果:
⑤ 比较的是内容,所以为true
⑥ 也许看到这个会感到迷茫,一开始我也迷茫。后来一想,这种情况str6则是在常量池中进行的拼接(若存在,则直接指向;若不存在,拼接创建)
今天的文章关于Java堆栈的理解与说明分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/24437.html