Java内存列表

当jvm运行起来的时候,它会向系统申请一片内存区,并将这块内存分出一部分存储程序创建的对象,传递给方法的参数,返回值,局部变量等等,我们将这块内存称之为“运行时数据区”。

初学的时候把Java内存分为堆内存和栈内存,这种分法是比较粗糙的。

仔细来看,运行时数据区可以划分成程序计数器(PC寄存器)、本地方法栈、虚拟机栈(Java栈)、堆、方法区、运行时常量池。

程序计数器(PC寄存器):Java是多线程的,每个线程都需要一个独立的程序计数器,以控制程序的分支、循环、跳转、异常处理等基础操作。

虚拟机栈(Java栈):和程序计数器(PC寄存器)一样是线程私有的。每个线程可以有多个方法,而每个方法被执行的时候都会同时创建一个栈帧,用来存储局部变量,操作数栈,动态链接,返回地址(方法出口)等信息。再次注意的是:其中局部变量(各种基本类型的变量和对象的引用变量)只是此栈内存中的一部分。

本地方法栈:与虚拟机栈(Java栈)所发挥的作用相似,区别在于本地方法栈是为虚拟机使用到的Native方法服务。

堆:线程共享。所有的对象实例和数组都在堆上分配。

方法区:线程共享。用于存储已被虚拟机加载的类信息、常量、静态变量等。注意的是:虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它也称作非堆

运行时常量池:方法区的一部分。存放编译期生成的各种字面量(文本字符串、声明为final的常量值)和符号引用(类和接口的全限定名、字段的名称和描述符、方法的名称和描述符)。

对象池机制:常量池。

String str1 = "abc";
String str2 = "abc";
创建了一个对象,原因是:在JAVA虚拟机(JVM)中存在着一个字符串池,其中保存着很多String对象,并且可以被共享使用,因此它提高了效率。
由于String类是final的,它的值一经创建就不可改变,因此我们不用担心String对象共享而带来程序的混乱。
字符串池由String类维护,我们可以调用intern()方法来访问字符串池。
我们再回头看看String str1="abc";这行代码被执行的时候,JAVA虚拟机首先在字符串池中查找是否已经存在了值为"abc"的这么一个对象,
它的判断依据是String类equals(Object obj)方法的返回值。如果有,则不再创建新的对象,直接返回已存在对象的引用;
如果没有,则先创建这个对象,然后把它加入到字符串池中,再将它的引用返回。因此,是创建了一个对象。
关于基本类型以及提供其包装类提供的方法这里就不一一表述了。记得自动装箱和拆箱是JDK1.5的时候提出的。
同时需要注意的是包装类中提供的和String相互转化的方法以及包装类之间转化的方法,这个需要练习。
这里只讲解:byte i = "128";中128这个数值存放在内存的哪里。
Character a = 127;
Character b = 127;
System.out.println(a == b);
System.out.println(a.equals(b));

System.out.println("------------------------------------");

Character a1 = 128;
Character b1 = 128;
System.out.println(a1 == b1);
System.out.println(a1.equals(b1));

System.out.println("------------------------------------");

char a2 = 127;
char b2 = 127;
System.out.println(a2 == b2);

输出:
true                               
true                               
------------------------------------
false                              
true                               
------------------------------------
true  
解释:Java为了提高性能提供了对象池机制,和String类一样,Java的八种基本类型的包装类中的六种也有对象池机制。
这六种包装类是:Byte,Short,Integer,Long,Character,Boolean。不同的是,这六种基本类型的包装类使用对象池的前提是数值要大于127。

原文地址:https://www.cnblogs.com/shuaixianbohou/p/3936071.html