成为一个菜鸟般的码农,对于java的存储也是要了解一些的。
存储我们一般是存储在RAM(随机存储器:可读可写)中,与之相对的是ROM(只读存储器),好,闲话不多说,简单看下java存储。
java存储分为堆、栈、常量池,初接触java 的同学可能对这一部分比较模糊。
我们知道,java有基础类型(int,short,byte,long,float,char,double,char)和其他类型,根据这两种类型,存储是有一些区别的。
我们先简单的了解下定义(直接cp):
堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。在单片机应用中,堆栈是个特殊的存储区,主要功能是暂时存放数据和地址,通常用来保护断点和现场。要点:堆,队列优先,先进先出(FIFO—first in first out)栈,先进后出(FILO—First-In/Last-Out)。
直白一点,我们创建一个对象;
String zhan = new String("dui");
从上面的定义,我们可以看出,我们新建了一个对象new String("dui"),这个对象就是存储在堆内存中的。
堆内存用来存放由new创建的对象和数组。 在堆中分配的内存,最终由Java虚拟机的自动垃圾回收器来管理,这个是无法控制的。
(String zhan)这个是存储在栈内存中的,
在函数中定义的一些基本类型的变量数据和对象的引用变量都在函数的栈内存中分配。当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当该变量退出该作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。
常量池是指在编译期确定,并被保存在.class文件中的一些数据。
堆与栈
Java的堆是一个运行时数据区,类的(对象从中分配空间。这些对象通过new、newarray、 anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态 分配内存,存取速度较慢。
栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。
经典题目:【1】 String a = "ab"; String bb = "b"; String b = "a" + bb; System.out.println((a == b)); //result = false 【2】 String a = "ab"; final String bb = "b"; String b = "a" + bb; System.out.println((a == b)); //result = true 【3】 String a = "ab"; final String bb = getBB(); String b = "a" + bb; System.out.println((a == b)); //result = false private static String getBB() { return "b"; }
对于基础类型的变量和常量,变量和引用存储在栈中,常量存储在常量池中。
int i1 = 9; int i2 = 9; int i3 = 9; public static final int INT1 = 9; public static final int INT2 = 9; public static final int INT3 = 9;
编译器先处理int i1 = 9;首先它会在栈中创建一个变量为i1的引用,然后查找栈中是否有9这个值,如果没找到,就将9存放进来,然后将i1指向9。接着处理int i2 = 9;在创建完i2的引用变量后,因为在栈中已经有9这个值,便将i2直接指向9。这样,就出现了i1与i2同时均指向9的情况。最后i3也指向这个9。
想了下,加个图,希望能有所帮助,谢谢~
借鉴于大神:https://www.cnblogs.com/SaraMoring/p/5687466.html