软件构造笔记 8.1 Metrics, Principles, and Methods of Construction for Performance

1.内存管理

系统和应用级别的内存管理

本机内存是分配给一个进程的物理内存,由OS管理。cpu执行指令,从内存读/写数据,在虚拟内存空间给进程分配内存,并与物理内存建立映射表

因为内存不足,所以要考虑高效率的内存管理问题,动态分配和回收内存,复用已回收的内存。

对象在heap堆中分配内存,对象引用指向其他对象在堆中的起始地址;非基本数据类型的变量等价于对象引用;每个对象可包含一组变量,每个变量可指向其他对象的引用;对象引用只指向一个其他对象,而一个对象可被多个其他对象引用。


2.三种对象管理模式

静态内存分配在编译阶段就确定好了内存分配。

动态内存分配在运行时动态分配内存,建立新的内存对象,基于堆和栈的内存管理都是动态分配。


差异在于如何和何时再程序对象与内存对象之间建立联系。

Static mode:在将程序load进内存的时候或开始执行的时候,确定所有对象的分配,不支持递归,不支持动态创建的可变长的复杂数据类型。

Stack-based mode:存储方法调用及方法执行中的局部数据,无法支持复杂类型。

Heap-based mode:在一块内存里分为多个小块,每块包含一个对象,或者未被使用。代码中的一个变量可以在不同时间被关联代不同的内存对象上,无法在编译阶段确定。内存对象也可以进一步指向其他对象。堆是自由模式的内存管理,动态分配,可管理复杂的动态数据类型。适用于:某些对象的延续时间比创建它的方法延续时间更长;递归、长度可变的数据结构;经常使用不限定长度的数据结构。

3.Java内存管理模型:关注JVM如何进行基于”堆“和”栈“的内存管理


每个线程在JVM中都有自己的栈,管理局部数据,各栈之间不可见。所有局部的基本数据类型都在栈上创建,多线程之间传递数据,是通过复制而非引用。

所有对象都在堆上创建,即使是局部变量的对象。



堆上创建的对象可被所有线程共享引用;可访问对象,就可以访问对象内的成员;如果两个线程调用一个对象上的某个方法,它们分别保留该方法局部变量的拷贝。


4.垃圾回收

内存回收的模式

在静态内存分配模式下,无需进行内存回收,所有都是已确定的;

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

在堆上进行内存空间回收最复杂——无法提前知道某个Object是否已变得无用。

可达和不可达

内存回收的首要问题是把可达对象和不可达对象分离开来。

通常,root包括:静态区域的数据;寄存器;目前执行栈中数据指向的内存对象。

从root可达的对象是活对象,不可达是死对象。


垃圾回收器根据对象的活性,即从root的可达性来决定是否回收该对象的内存。死对象就是需要回收的垃圾。

垃圾回收GC:识别垃圾对象,把其中占用的内存加以回收。

健全性:每个收集到的对象都无法访问。

完整性:每一个不可达的对象都将被收集。

5.垃圾回收的基本算法

引用计数

对库中的每个物体上加上一个注释,指出对物体的实时参考数量。如果一个对象的引用计数为零,则抛出该对象(它已经死了)。

基本思想:为每个对象存储一个计数RC,当有其他引用指向它是,RC++;当其他引用与其断开时,RC--;若RC==0,则回收它。


优点是简单、计算代价分散,幽灵时间段。

缺点是不全面、并发支持弱、占用额外内存空间。

标记-清除

在需要的物体上放置一个注释(根部)。然后以递归方式记录活体对象所需的任何内容。之后,检查所有对象并丢弃没有注释的对象。

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


优点是指针操作无运行时间开销、与增变器松散耦合、不移动对象。

缺点是在扫描期间,必须检查内存中的每个位置、碎片化,幽灵时间长。

标记-整理

把标记加在需要的物体上,将任何带有标记的东西移到库的后面。回收库前面的所有对象(全部死掉)。


复制

将需要的物体移动到新的库。然后递归地移动新库中对象所需的任何东西。之后,回收旧库(其中的任何物体已经死亡)。

与标记-整理顶点区别在于不是在同一个区域内进行整理,而是将live对象全部复制到另外一个区域。


6.JVM中的垃圾回收

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

HotSpot虚拟机(Sun JVM)有三个主要空间:young generation、oldgeneration、permanent generation



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

针对老年代,这里的对象有很高的幸存度,使用标记-清除或标记-整理算法

只有当某个区域不能再为对象分配内存时,才启动GC,针对young generation,使用minor GC进行垃圾回收Minor GC所需时间较短,如果经历多次minor GC仍存活 ,将其复制到oldgeneration

如果old generation满了,则启动full GC,此时无法进行下一次minorGC,minor GC和full GC 独立进行以减少代价

perm generation满了之后,无法存储更多的元数据,也启动full GC

7.JVM中垃圾回收的调整

尽可能减少GC时间,一般不超过程序执行时间的百分之5;一旦初始分配给程序的内存满了,就抛出内存溢出异常;再启动程序时,可为其配置内存分配的具体大小。

堆的大小决定JVM将会以何种频度进行GC,每次GC的时间多长。这两个指标具体多少为优,需要针对特定应用来分析,较大的堆会导致发生GC次数较少,但时间变长。Old generation的尺寸不需要设置,根据其他参数的取值可计算得到。


堆的大小决定JVM将会以何种频度进行GC,每次GC的时间多长。这两个指标具体多少为优,需要针对特定应用来分析,较大的堆会导致发生GC次数较少,但时间变长。Old generation的尺寸不需要设置,根据其他参数的取值可计算得到。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值