堆、栈

1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

2、堆区(heap)— 是一个可动态申请的内存空间(其记录空闲内存空间的链表由操作系统维护),在java中,所有使用new xxx()构造出来的对象都在堆中存储一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。分配方式类似于链表

  • 堆是全局的,堆栈是每个函数进入的时候分一小块,函数返回的时候就释放了,静态和全局变量new得到的变量,包装类数据,都放在堆中,局部变量放在栈中,所以函数返回,局部变量就全没了。

  • 堆的优势是可以动态地分配内存大小,所有使用new xxx()构造出来的对象都在堆中存储,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢

  • 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共享

3、常量池:存放字符串常量和基本类型常量,常量池的好处是为了避免频繁的创建和销毁对象而影响系统性能,其实现了对象的共享,存在于栈中

4、String是一个特殊的包装类数据

  • new String()是规范的类的创建过程,即在Java中,一切都是对象,而对象是类的实例,全部通过new()的形式来创建

  • 关于String str = "abc"的内部工作。Java内部将此语句转化为以下几个步骤:

    (1) 先定义一个名为str的对String类的对象引用变量放入中。

    (2) 在常量池中查找是否存在内容为"abc"字符串对象。

    (3) 如果不存在则在常量池中创建"abc",并让str引用该对象。

    (4) 如果存在则直接让str引用该对象

在JAVA中,有六个不同的地方可以存储数据:

  1. 寄存器(register):这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部。但是寄存器的数量极其有限,所以寄存器由编译器根据需求进行分配。你不能直接控制,也不能在程序中感觉到寄存器存在的任何迹象。

  2. 栈(stack):存放基本类型的变量数据和对象的引用。位于通用RAM中,但通过它的“堆栈指针”可以从处理器哪里获得支持。堆栈指针若向下移动,则分配新的内存;若向上移动,则释放那些内存。这是一种快速有效的分配存储方法,仅次于寄存器。创建程序时候,JAVA编译器必须知道存储在堆栈内所有数据的确切大小和生命周期,因为它必须生成相应的代码,以便上下移动堆栈指针。这一约束限制了程序的灵活性。

  3. 堆(heap):一种通用性的内存池(也存在于RAM中),用于存放所有的JAVA对象。堆不同于堆栈的好处是:编译器不需要知道要从堆里分配多少存储区 域,也不必知道存储的数据在堆里存活多长时间。因此,在堆里分配存储有很大的灵活性。当你需要创建一个对象的时候,只需要new写一行简单的代码,当执行 这行代码时,会自动在堆里进行存储分配。当然,为这种灵活性必须要付出相应的代价,用堆进行存储分配比用堆栈进行存储存储需要更多的时间。

  4. 静态存储(static storage):这里的“静态”是指“在固定的位置”。静态存储里存放程序运行时一直存在的数据。你可用关键字static来标识一个对象的特定元素是静态的,但JAVA对象本身从来不会存放在静态存储空间里。

  5. 常量存储(constant storage):存放字符串常量和基本类型常量(public static final)。 常量值通常直接存放在程序代码内部,这样做是安全的,因为它们永远不会被改变。

  6. 非RAM存储:硬盘等永久存储空间。如果数据完全存活于程序之外,那么它可以不受程序的任何控制,在程序没有运行时也可以存在。

你可能感兴趣的:(堆、栈)