《软件构造》第八章复习要点对照

内存管理模型:堆、栈

所有局部的基本类型都在栈上创建,所有对象都在堆上创建

多线程之间传递数据,是通过复制而非引用

即使是局部变量的object,也是在堆上创建

堆上创建的对象可被所有线程共享引用,可访问对象,就可以访问对象内的成员变量

JVM模型:


栈的用途:

1.用于传参

2.方法的返回值

3.在计算表达式时存储中间结果

4.存储局部变量

堆的用途:

1.对象

2.Array

3.通过使用“new”操作符

Garbage Collection

三种模式下的空间回收:

1.在静态内存分配模式下,无需进行内存回收,所有都是已确定的(对于每一个对象,都有一个附加的实体;只要实体是活动的,执行就需要保留对象的空间。因此在适当的意义上不可能进行回收。)

2。在栈上进行内存空间回收:按block (某个方法)整体进行

3.在heap 上进行内存空间回收,最复杂—— 无法 提前预知某个object 是否已经变得无用。

Reachable and Unreachable Objects:

在系统执行的任何时候,origins/roots的集合都由根对象组成

只要对象仍然可以从程序计算的某些部分获得,它就可以存活。这些origins/roots的任何相关的、直接的或间接的都是可到达的,而任何其他的对象都是不可达的

In common language implementations roots include
– Words in the static area 静态区域的数据
– Registers 寄存器
– Words on the execution stack that point into the heap. 目前的执行栈中的数据所指向的内存对象

活对象:从root 可达的对象

死对象:从root

垃圾回收器根据对象的“活性”( 从root 的可达性) 来决定是否回收该对象的内存

GC的成本指标:执行时间、延迟时间、内存使用情况、其他重要指标

可靠性:收集到的每个对象都是不可达的。

完整性:所有不可达的对象都会被收集。

GC的四种基本算法

Reference counting  引用计数

在你的车库里对每一个对象都做一个记录,表明对该对象的引用次数。如果一个对象的引用计数变为0,则将该对象抛出(它已死)。

为每个object 存储一 个计数RC ,当有其他reference 指向它时,RC++ ;当其他reference 与其断开时,RC-- ;如果RC==0 ,则回收它。

引用计数方法的优点:简单、计算代价分散 ,“幽灵时间”短 ->0

引用计数方法 的缺点:不全面(容易漏掉循环引用的对象)、并发支持较弱、占用额外内存空间等。

 Mark-Sweep  标记- 清除
-在你需要的对象(根)上做个说明。
-然后递归地在一个活动对象需要的任何东西上放一个注释。

-检查所有对象,剔除无注释的对象。

为每个object 设定状态位(live/dead) 并记录,即mark 阶段;将标记为dead 的对象进行清理,即sweep 可阶段。

Advantages of mark-sweep
 Comprehensive: cyclic garbage collected naturally
 No run-time overhead on pointer manipulations
 Loosely coupled to mutator
 Does not move objects
– Does not break any mutator invariants
– Optimizer-friendly
– Requires only one reference to each live object to be discovered

(rather than having to find every reference)


Disadvantages of mark-sweep
 Stop/start nature leads to disruptive pauses and long zombie time.
 Every location in memory must be examined during the sweep
stage of this algorithm - this can be time-consuming and the
complexity is O(heap) rather than O(live)
– Every live object is visited in mark phase
– Every object, alive or dead, is visited in sweep phase
 Degrades with residency (heap occupancy)
– The collector needs headroom in the heap to avoid thrashing
– Example: lots of marking to do if heap is full
 Fragmentation: Can leave several gaps in used memory when
objects are swept out. This fragmentation cause serious performance
problems for applications which make heavy memory demands.
 Tracing collectors must be able to find roots.

Mark-Compact  标记- 整理
-在你需要的物品上做笔记。
-把任何有纸条的东西搬到车库里。

-把车库前的东西都烧掉(都死了)。

Copying  复制
-把你需要的东西搬到新的车库。
-然后递归地移动新车库中对象需要的任何东西。

-然后,烧掉旧车库(里面的任何东西都是死的)!

CopyGC的优点
压实免费
对于所有对象大小,分配非常便宜。
外置检查是指针比较。
只需增加要分配的自由指针
只处理活动数据(通常是堆的一小部分)
固定的空间开销
自由和扫描的指针
可以在用户数据上写入转发地址
综合:自然回收循环垃圾

实现合理有效的复制GC非常简单

CopyGC的缺点
停止与复制可能是破坏性的
降解与居住
需要其他简单收集器的两倍地址空间
触摸两倍的页面
权衡反对分裂
复制大型对象的成本。
长寿命数据可能被反复复制。
所有引用必须更新
移动的物体可能会破坏可变子不变量

宽度优先的复制可能会干扰本地模式

JVM的内存管理模型

 Java GC 将堆分为不同的区域,各区域采用不同的GC 策略,以提高GC 的效率


针对年轻代: 只 有 一小部分对象可较长时间存活,故采用copy 算法减少GC代价

针对年老代:这里的对象有很高的幸存度,使用Mark-Sweep 或Mark-Compact

只有当某个区域不能再为对象分配内存时(满),才启动GC

针对young generation , 使用minor GC,Minor GC所需时间较短,如果历经多次minor GC仍存活下来,将其copy到old generation,如果old generation 满了,则启动full GC,  当perm generation 满了之后,无法存储更多的元数据,也启动full GC

JVM中的垃圾收集调优:

尽可能减少GC 时间,一般不超过程序执行时间的5%

一旦初始分配给程序的内存满了,就抛出内存溢出异常

在启动程序时,可为其配置内存分配的具体大小


堆的大小决定着VM 将会以何种频度进行GC 、每次GC的时间多长

较大的heap会导致较少发生GC,但每次GC时间很长


通过 以下 参数 设置young generation 的 尺寸
– -XX: NewSize=<n>[g|m|k] The initial and minimum size of the
young generation space. <n> is the size. [g|m|k] indicates whether the
size should be interpreted as gigabytes, megabytes, or kilobytes.
– -XX: MaxNewSize=<n>[g|m|k] The maximum size of the young
generation space.
– -Xmn<n>[g|m|k] Sets the initial, minimum, and maximum size of the
young generation space.
– -XX:NewRatio=<n> The ratio between the young and old generation is
1:n. In other words, the combined size of the eden and survivor spaces
will be 1/(1+n) of the total heap size.
– -XX:SurvivorRatio=<n> The ratio between eden and a survivor space
to n:1, i.e., each survivor space will be 1/n the size of eden, and thus

1/(2+n) the size of the young.

old generation 的尺寸不需设置,根据其他各参数的取值可计算得到
– The initial old generation space size is the value of -Xms minus -
XX:NewSize.
– The maximum old generation space size is the value of -Xmx minus -
XX:MaxNewSize.
– If -Xms and -Xmx are set to the same value and -Xmn is used, or -
XX:NewSize is the same value as -XX:MaxNewSize, then the old
generation size is -Xmx (or -Xms) minus -Xmn.

猜你喜欢

转载自blog.csdn.net/weixin_39627422/article/details/80772199