`
tibaloga
  • 浏览: 871805 次
文章分类
社区版块
存档分类
最新评论

java内存

 
阅读更多

在java视频中,一直强调java内存的重要性,如果真正理解 了java内存的分配情况和程序运行时的java内存,那么你会对 java编程的思想,会更加深刻。

Java内存分配与管理是Java的核心技术之一,Java的内存分配有三种,

一、静态存储区:内存在程序编译时就分配好了,比如静态变量;

二、栈区(stack):各种原始数据类型的局部变量都是在栈上创 建的,当程序退出该变量的作用范围的时候,这个变量的内存会被自动释放。

栈式存储分配也可称为动态存储分配,是由一个类似于堆栈的运行栈来实现的.和静态存储分配相反,在栈式存储方案中,程序对数据区的需求在编译时是完全未知的,只有到运行的时候才能够知道,但是规定在运行中进入一个程序模块时,必须知道该程序模块所需的数据区大小才能够为其分配内存.和我们在数据结构所熟知的栈一样,栈式存储分配按照先进后出的原则进行分配。

在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配。

1.基本类型的变量:如:(int,short,long, byte ,float , double , Boolean ,char),栈有个很重要的特殊性,就是存在栈中的数据可以共享,例如:

Int a=1;

Int b=1;

Int a =3;

Java编译器会先处理 int a=1;首先它会在栈中创建一个变量为a的引用,然后在栈中查找是否有“1”这个值,如果没有找到,就将1存放到栈中,然后将a指向1,接着处理b=1,在创建玩b的引用变量后,因为栈中已经存在“1”这个值,所以,直接将b指向“1”,这就出现了a和b同时指向“1”的情况。

然后处理a=3;,在栈中没有找到“3”,所以把“3”放到栈中,接着就把a指向“3”,这个地址,因此a值的变化不会影响到b 的值。这就是栈的数据共享,节省了很大的内存。在程序编译的时候那些常量(1和3),都是放在常量池中的。

2.对象引用变量:在创建一个对象(实例化new)后,在栈中定义一个特殊的变量,让栈中的这个变量取值等于数组或者对象在堆内存中的首地址,这就变成了引用变量,引用变量就相当于是为数组和对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。

如:String str = new String(“Hello”);

首先在常量池中有一个“Hello”,处理后,把“Hello”复制到堆中一份,在栈中创建一个对象引用变量,指向堆中“Hello”的首地址。

故:栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量数据(int,short, long, byte, float, double, boolean, char)和对象句柄(引用)。

三、堆区(heap):对象(包括数组)都是在堆中创建的。程序在 运行的时候用new关键字来创建对象,对象创建时会在堆中为其分配内存。在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。

java的堆是一个运行时数据区,类的(对象从中分配空间。这些对象通过new、newarray、 anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存 大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态 分配内存,存取速度较慢。

堆主要用来存放对象的堆是应用程序在运行的时候请求操作系统分配给自己内存,由于从操作系统管理的内存分配,所以在分配和销毁时都要占用时间,因此用堆的效率非常低.但是堆的 优点在于,编译器不必知道要从堆里分配多少存储空间,也不必知道存储的数据要在堆里停留多长的时间,因此,用堆保存数据时会得到更大的灵活性。事实上,面 向对象的多态性,堆内存分配是必不可少的,因为多态变量所需的存储空间只有在运行时创建了对象之后才能确定.

因为多态变量所需的存储空间只有在运行时创建了对象之后才能确定,要求创建一个对象时会在堆里自动进行数据的保存.当然,为达到这种灵活性,必然会付出一定的代价:在堆里分配存储空间时会花 掉更长的时间!这也正是导致我们刚才所说的效率低的原因


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics