??xml version="1.0" encoding="utf-8" standalone="yes"?>成人精品网站在线观看,欧美一区二区视频在线观看2020,亚洲伊人观看http://www.aygfsteel.com/liucunjie/category/8092.htmlJeff's Java Homezh-cnSat, 01 Dec 2007 06:50:45 GMTSat, 01 Dec 2007 06:50:45 GMT60Java 中的堆和栈(转)http://www.aygfsteel.com/liucunjie/archive/2007/11/30/164165.htmlJeff's Java HomeJeff's Java HomeFri, 30 Nov 2007 01:18:00 GMThttp://www.aygfsteel.com/liucunjie/archive/2007/11/30/164165.htmlhttp://www.aygfsteel.com/liucunjie/comments/164165.htmlhttp://www.aygfsteel.com/liucunjie/archive/2007/11/30/164165.html#Feedback0http://www.aygfsteel.com/liucunjie/comments/commentRss/164165.htmlhttp://www.aygfsteel.com/liucunjie/services/trackbacks/164165.htmlJava 中的堆和?/strong>

单的_
Java把内存划分成两种Q一U是栈内存,一U是堆内存?nbsp;  
   
  在函C定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配?nbsp;  
   
  当在一D代码块定义一个变量时QJava在栈中个变量分配内存空_当超q变量的作用域后QJava会自动释放掉变量所分配的内存空_该内存空间可以立卌另作他用?nbsp;  
   
  堆内存用来存攄new创徏的对象和数组?nbsp;  
   
  在堆中分配的内存Q由Java虚拟机的自动垃圾回收器来理?nbsp;  
   
  在堆中生了一个数l或对象后,q可以在栈中定义一个特D的变量Q让栈中q个变量的取值等于数l或对象在堆内存中的首地址Q栈中的q个变量成了数l或对象的引用变量?nbsp;  
   
  引用变量q当于是ؓ数组或对象v的一个名Uͼ以后可以在E序中用栈中的引用变量来访问堆中的数组或对象?nbsp;  
   


           

具体的说Q?br /> 栈与堆都是Java用来在Ram中存放数据的地方。与C++不同QJava自动理栈和堆,E序员不能直接地讄栈或堆?
          Java的堆是一个运行时数据?cȝ(对象从中分配I间。这些对象通过new、newarray、anewarray和multianewarray{指令徏立,它们不需要程序代码来昑ּ的释放。堆是由垃圾回收来负责的Q堆的优势是可以动态地分配内存大小Q生存期也不必事先告诉编译器Q因为它是在q行时动态分配内存的QJava的垃圾收集器会自动收走这些不再用的数据。但~点是,׃要在q行时动态分配内存,存取速度较慢?
         栈的优势是,存取速度比堆要快Q仅ơ于寄存器,栈数据可以共享。但~点是,存在栈中的数据大与生存期必L定的,~Z灉|性。栈中主要存放一些基本类型的变量Q?int, short, long, byte, float, double, boolean, charQ和对象句柄?
         栈有一个很重要的特D性,是存在栈中的数据可以共享。假设我们同时定义:
int a = 3;
int b = 3Q?
~译器先处理int a = 3Q首先它会在栈中创徏一个变量ؓa的引用,然后查找栈中是否?q个|如果没找刎ͼ将3存放q来Q然后将a指向3。接着处理int b = 3Q在创徏完b的引用变量后Q因为在栈中已经?q个|便将b直接指向3。这P出Ca与b同时均指?的情c这Ӟ如果再oa=4Q那么编译器会重新搜索栈中是否有4|如果没有Q则?存放q来Qƈ令a指向4Q如果已l有了,则直接将a指向q个地址。因此a值的改变不会影响到b的倹{要注意q种数据的共享与两个对象的引用同时指向一个对象的q种׃n是不同的Q因U情况a的修改ƈ不会影响到b, 它是q译器完成的,它有利于节省I间。而一个对象引用变量修改了q个对象的内部状态,会媄响到另一个对象引用变量?

String是一个特D的包装cL据。可以用Q?
String str = new String("abc");
String str = "abc";
两种的Ş式来创徏Q第一U是用new()来新建对象的Q它会在存放于堆中。每调用一ơ就会创Z个新的对象?
而第二种是先在栈中创Z个对Stringcȝ对象引用变量strQ然后查找栈中有没有存放"abc"Q如果没有,则将"abc"存放q栈Qƈ令str指向”abc”Q如果已l有”abc” 则直接ostr指向“abc”?

           比较c里面的数值是否相{时Q用equals()ҎQ当试两个包装cȝ引用是否指向同一个对象时Q用==Q下面用例子说明上面的理论?
String str1 = "abc";
String str2 = "abc";
System.out.println(str1==str2); //true
可以看出str1和str2是指向同一个对象的?

String str1 =new String ("abc");
String str2 =new String ("abc");
System.out.println(str1==str2); // false
用new的方式是生成不同的对象。每一ơ生成一个?
       因此用第一U方式创建多?#8221;abc”字符?在内存中其实只存在一个对象而已. q种写法有利与节省内存空? 同时它可以在一定程度上提高E序的运行速度Q因为JVM会自动根据栈中数据的实际情况来决定是否有必要创徏新对象。而对于String str = new String("abc")Q的代码Q则一概在堆中创徏新对象,而不其字符串值是否相{,是否有必要创建新对象Q从而加重了E序的负担?
       另一斚w, 要注? 我们在用诸如String str = "abc"Q的格式定义cLQL惛_然地认ؓQ创ZStringcȝ对象str。担心陷阱!对象可能q没有被创徏Q而可能只是指向一个先前已l创建的对象。只有通过new()Ҏ才能保证每次都创Z个新的对象。由于Stringcȝimmutable性质Q当String变量需要经常变换其值时Q应该考虑使用StringBufferc,以提高程序效率?br />



java中内存分配策略及堆和栈的比较
2.1 内存分配{略
按照~译原理的观?E序q行时的内存分配有三U策?分别是静态的,栈式?和堆式的.
静态存储分配是指在~译时就能确定每个数据目标在q行时刻的存储空间需?因而在~译时就可以l他们分配固定的内存I间.q种分配{略要求E序代码中不允许有可变数据结?比如可变数组)的存?也不允许有嵌套或者递归的结构出?因ؓ它们都会D~译E序无法计算准确的存储空间需?
栈式存储分配也可UCؓ动态存储分?是由一个类g堆栈的运行栈来实现的.和静态存储分配相?在栈式存储方案中,E序Ҏ据区的需求在~译时是完全未知?只有到运行的时候才能够知道,但是规定在运行中q入一个程序模块时,必须知道该程序模块所需的数据区大小才能够ؓ其分配内?和我们在数据l构所熟知的栈一?栈式存储分配按照先进后出的原则进行分配?
静态存储分配要求在~译时能知道所有变量的存储要求,栈式存储分配要求在过E的入口处必ȝ道所有的存储要求,而堆式存储分配则专门负责在编译时或运行时模块入口处都无法定存储要求的数据结构的内存分配,比如可变长度串和对象实例.堆由大片的可利用块或I闲块组?堆中的内存可以按照Q意顺序分配和释放.

2.2 堆和栈的比较
上面的定义从~译原理的教材中ȝ而来,除静态存储分配之?都显得很呆板和难以理?下面撇开静态存储分?集中比较堆和?
从堆和栈的功能和作用来通俗的比?堆主要用来存攑֯象的Q栈主要是用来执行程序的.而这U不同又主要是由于堆和栈的特点决定的:
在编E中Q例如C/C++中,所有的Ҏ调用都是通过栈来q行?所有的局部变?形式参数都是从栈中分配内存空间的。实际上也不是什么分?只是从栈向上用p,好像工厂中的传送带(conveyor belt)一?Stack Pointer会自动指引你到放东西的位|?你所要做的只是把东西放下来就?退出函数的时候,修改栈指针就可以把栈中的内容销?q样的模式速度最? 当然要用来运行程序了.需要注意的?在分配的时?比如Z个即要调用的程序模块分配数据区?应事先知道这个数据区的大?也就说是虽然分配是在E序q行时进行的,但是分配的大多是定?不变?而这?大小多少"是在~译时确定的,不是在运行时.
堆是应用E序在运行的时候请求操作系l分配给自己内存Q由于从操作pȝ理的内存分?所以在分配和销毁时都要占用旉Q因此用堆的效率非常?但是堆的优点在于,~译器不必知道要从堆里分配多存储空_也不必知道存储的数据要在堆里停留多长的时?因此,用堆保存数据时会得到更大的灵zL。事实上,面向对象的多态?堆内存分配是必不可少?因ؓ多态变量所需的存储空间只有在q行时创Z对象之后才能定.在C++中,要求创徏一个对象时Q只需?new命o~制相关的代码即可。执行这些代码时Q会在堆里自动进行数据的保存.当然Qؓ辑ֈq种灉|性,必然会付Z定的代h:在堆里分配存储空间时会花掉更长的旉Q这也正是导致我们刚才所说的效率低的原因,看来列宁同志说的?人的优点往往也是人的~点,人的~点往往也是人的优点(晕~).


2.3 JVM中的堆和?
JVM是基于堆栈的虚拟?JVM为每个新创徏的线E都分配一个堆?也就是说,对于一个JavaE序来说Q它的运行就是通过对堆栈的操作来完成的。堆栈以帧ؓ单位保存U程的状态。JVM对堆栈只q行两种操作:以为单位的压栈和出栈操作?
我们知道,某个U程正在执行的方法称为此U程的当前方?我们可能不知?当前Ҏ使用的UCؓ当前帧。当U程ȀzM个JavaҎ,JVM׃在线E的 Java堆栈里新压入一个。这个自然成ؓ了当前.在此Ҏ执行期间,q个帧将用来保存参数,局部变?中间计算q程和其他数?q个帧在q里和编译原理中的活动纪录的概念是差不多?
从Java的这U分配机制来?堆栈又可以这L?堆栈(Stack)是操作系l在建立某个q程时或者线E?在支持多U程的操作系l中是线E?个线E徏立的存储区域Q该区域h先进后出的特性?
每一个Java应用都唯一对应一个JVM实例Q每一个实例唯一对应一个堆。应用程序在q行中所创徏的所有类实例或数l都攑֜q个堆中,q由应用所有的U程׃n.跟C/C++不同QJava中分配堆内存是自动初始化的。Java中所有对象的存储I间都是在堆中分配的Q但是这个对象的引用却是在堆栈中分配,也就是说在徏立一个对象时从两个地斚w分配内存Q在堆中分配的内存实际徏立这个对象,而在堆栈中分配的内存只是一个指向这个堆对象的指?引用)而已?


Jeff's Java Home 2007-11-30 09:18 发表评论
]]>
վ֩ģ壺 ̫| | | | ԫ| | ʼ| Դ| | | | | | | | Ȩ| Ȫ| | ¸| | | ½| | | | | ϽϽ| | | | | ڰ| ˳| Ӽ| ʡ| º| Ҧ| Ԫ| ɽ| ũ| С|