在java中内存的占用主要分为四块:静态区、代码区、堆、栈。其中,堆和栈使用最多。
1、静态区:内存在程序编译时就分配好的区域,主要存放一些静态变量(static的);
2、代码区:存放程序方法的二进制代码,而且是多个对象共享一个代码空间区域;
3、堆(heap):运行时数据区,主要存放new出来的一些对象和数组;
4、栈(stack):主要保存一些基本的数据类型,和对象的引用变量;
5、常量池:存放一些字符串常量和基本类型常量。
堆(heap)内存
堆(heap)内存,是java虚拟机所管理的内存中最大的一块,它的唯一用途是存放对象实例(几乎所有对象实例都在这里),是被所有线程共享的一块内存。在java虚拟机规范中,堆可处理物理上不连续、逻辑上连续的内存空间。若堆中没有内存可供实例分配、且也无扩展时,会出现OutOfMemoryError。
堆(heap)的优点是,可以动态地分配内存大小,它是运行时动态分配内存的,所以生存期不必事先告诉编译器,其内存不能认为释放,java的垃圾回收器会自动收走不再使用的数据。
堆(heap)的缺点是:由于要在运行时动态分配内存,存取速度较慢。
栈(stack)内存
栈(stack)内存,程序运行时,用于存放局部变量、参数传递等。当一个方法执行时,每个方法都会建立自己的内存栈,此方法定义的变量会逐步放入这块栈内存里,方法执行结束、内存栈自动销毁,方法中的局部变量都在栈中。
当一段代码定义了一个局部变量时,java在栈中为其分配内存空间,当超过变量作用域时,被分配的内存空间会被java释放掉、立即另作他用。
栈(stack)内存的优点是:存取速度比堆快,仅次于CPU的寄存器,数据可以共享。
栈(stack)内存的缺点是:存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。
堆(heap)和栈(stack)实例理解
int [] array = new int[3]; 在内存中是如何定义的?
主函数先在栈中定义变量array,然后给array赋值,但等号右边是实体非具体数值,new关键字在堆中开辟空间,内存在存储数据时通过地址(一块连续的二进制)体现,给这个实体分配一个内存地址。数组在堆内存中的空间会默认初始化(未初始化是不能用的)。
给堆分配了一个地址,再把堆的地址赋给array,array就通过地址指向了堆中的数组,array想操纵数组时,是通过地址、而非直接把实体赋给他。
这种数据的类型就叫做引用数据类型,称为array引用了堆内存当中的实体。