JAVA 内存管理

 
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 是很慢 , 它的 需要 时间 .
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值