JAVA 内存管理

来源:互联网 发布:空手道俱乐部网络 编辑:程序博客网 时间:2024/05/06 01:47
 
1 内存分配策略
  
按照编译原理的,程序运行内存分配有三策略,是静,式的,和堆式的.
  
分配是指在编译时就能确定个数据目在运行刻的存需求,因而在编译时就可以分配固定的内存.这种分配策略要求程序代中不允 有可数据(比如可)的存在,也不允有嵌套或者递归构出,都会编译程序无法算准确的存需求.
  
式存分配也可称为动态分配,是由一个似于堆的运行实现.和静分配相反,式存方案中,程序数据区的需求在编译时是完全未知 的,只有到运行的候才能知道,但是定在运行中入一个程序模块时,知道程序模所需的数据区大小才能够为其分配内存.和我在数据构所熟知 的,式存分配按照先后出的原则进行分配。
  
分配要求在编译时能知道所有量的存要求,式存分配要求在程的入口知道所有的存要求,而堆式存分配则专门负责编译时或运行入口都无法确定存要求的数据构的内存分配,比如可变长度串和.堆由大片的可利用或空闲块组,堆中的内存可以按照任意序分配和.
2 堆和的比
 
上面的定编译原理的教材中总结而来,除静分配之外,得很呆板和以理解,下面撇分配,集中比堆和:
  
从堆和的功能和作用来通俗的比,堆主要用来存放象的,主要是用来行程序的.这种不同又主要是由于堆和的特点决定的:
  
程中,例如C/C++中,所有的方法用都是通过栈行的,所有的局部,形式参数都是从中分配内存的。实际上也不是什分配,只是从栈顶 向上用就行,就好像工厂中的(conveyor belt),Stack Pointer会自指引你到放西的位置,你所要做的只是把西放下来就行.退出函数的候,修改就可以把中的内容销毁.这样的模式速度最快, 当然要用来运行程序了.需要注意的是,在分配的,比如一个即将要用的程序模分配数据区,事先知道个数据区的大小,也就然分配是在程 序运行时进行的,但是分配的大小多少是确定的,,"大小多少"是在编译时确定的,不是在运行.
  
堆是用程序在运行的求操作系分配自己内存,由于从操作系管理的内存分配,所以在分配和销毁时都要占用时间,因此用堆的效率非常低.但是堆的 点在于,编译器不必知道要从堆里分配多少存,也不必知道存的数据要在堆里停留多时间,因此,用堆保存数据会得到更大的灵活性。事,面 向象的多,内存分配是必不可少的,态变量所需的存只有在运行时创建了象之后才能确定.C++中,要求建一个,只需用 new命令制相的代即可。些代码时,会在堆里自动进行数据的保存.当然,达到这种灵活性,必然会付出一定的代价:在堆里分配存间时会花 掉更时间也正是致我们刚才所的效率低的原因,看来列宁同志的好,人的点往往也是人的缺点,人的缺点往往也是人的(~).

3 JVM
中的堆和 
  JVM
是基于堆的虚.JVM为每个新建的线程都分配一个堆.也就是,于一个Java程序来,它的运行就是通过对的操作来完成的。堆帧为单位保存线程的状JVM行两操作:帧为单位的压栈和出操作。
 
知道,某个线程正在行的方法称线程的当前方法.可能不知道,当前方法使用的当前。当线程激活一个Java方法,JVM就会在线程的 Java里新入一个自然成了当前.在此方法行期,将用来保存参数,局部,间计程和其他数据.里和编译 原理中的活动纪录的概念是差不多的.
 
Java这种分配机制来看,又可以这样理解:(Stack)是操作系在建立某个或者线(在支持多线程的操作系中是线)为这线程建立的存区域,区域具有先后出的特性。
  
一个Java用都唯一对应一个JVM例,一个例唯一对应一个堆。用程序在运行中所建的所有类实例或数都放在个堆中,并由用所有的线程 共享.C/C++不同,Java中分配堆内存是自初始化的。Java中所有象的存都是在堆中分配的,但是象的引用却是在堆中分配,也 就是在建立一个从两个地方都分配内存,在堆中分配的内存实际建立象,而在堆中分配的内存只是一个指向个堆象的指(引用)而已。

4 GC
的思考
   Java
?JVM的存在当然是一个原因,但有人,Java,除了简单类(int,char)的数据,其它都是在堆中分配内存(所以Java的一切都是)也是程序慢的原因之一。
  
我的想法是(应该说代表TIJ),如果没有Garbage Collector(GC),上面的法就是成立的.堆不象连续的空,没有法指望堆本身的内存分配能象堆样拥般的速度,,你整理大的堆空,你几乎没有延的从堆中取新的空?
  
,GC站出来解决问题.都知道GC用来清除内存垃圾,出空供程序使用,GC也担了另外一个重要的任,就是要Java中堆 的内存分配和其他言中堆内存分配一,速度的问题几乎是众口一Java.要达到这样的目的,就必使堆的分配也能做到象,不用自己操心去找空.这样,GC除了负责清除Garbage,负责整理堆中的,把它们转移到一个Garbage纯净中无 隔的排列起来,就象堆中一样紧,这样Heap Pointer就可以方便的指向的起始位置,或者一个未使用的空,下一个需要分配内存"指引方向".因此可以这样说,垃圾收集影响了 象的建速度,听起来很怪,?
  
GC在堆中找到所有存活的象呢?前面,在建立一个,在堆中分配实际建立象的内存,而在堆中分配一个指向个堆象的指(引 用),只要在堆(也有可能在静)找到个引用,就可以跟踪到所有存活的.找到之后,GC将它从一个堆的中移到另外一个堆的,并 将它一个挨一个的排列起来,就象我上面的那,出了一个,但又不是先后出的分配,而是可以任意分配的,在速度可以保的情况下, Isnt it great?
  
但是,列宁同志,人的点往往也是人的缺点,人的缺点往往也是人的(~~).GC()的运行要占用一个线,本身就是一个降低程序运行性能 的缺陷,更何况线要在堆中把内存翻来覆去的折.如此,如上面所,堆中存活的象被搬移了位置,所有对这象的引用都要重新赋值.开销都会致性能的降低.
  
此消彼,GC()来的效益是否盖了它的缺点致的,我也没有太多的体会,Bruce Eckel Java的支持者,王婆瓜,不能全信.个人的感,Java是很慢,它的需要时间.
 
原创粉丝点击