当前位置:Gxlcms > PHP教程 > 一个类解耦成多个类,从实例化一个类到要实例化多个类,这样是不是增加了内存的消耗?

一个类解耦成多个类,从实例化一个类到要实例化多个类,这样是不是增加了内存的消耗?

时间:2021-07-01 10:21:17 帮助过:4人阅读

一个类解耦成多个类,从实例化一个类到要实例化多个类,这样是不是增加了内存的消耗?

回复内容:

一个类解耦成多个类,从实例化一个类到要实例化多个类,这样是不是增加了内存的消耗?

如果解耦得当,基本不会增加内存消耗,因为对象中的方法和参数虽然被分成到了不同的类中,但每个方法和参数占用空间都没有变,所有总体内存也没有变。只是在对象信息栈和指针上多占一些内存,不过这些基本都是可以忽略的。

内存可以批量生产,人要计划生育

如果所有用到这一个类的地方,都需要实例化解耦后的所有类,那这个类就没有必要解耦

但人工比内存贵得多

就单从语义来看,这是肯定的。
但是内存的消耗只是开发的一部分,毕竟还要考虑开发成本,维护成本


看起来没有太大的差别,只是CPU占用率后者明显大一些,当然我只是随便测了一下,仅供参考~

这种过程可以将功能更加细化,这样维护起来就能更加轻松

因为一个类,就算什么都不定义,也是会有固定的内存消耗的(主要就是class的一些meta信息了),所以理论上类越多这部分开销越大。

然而这部分能占多少呢?几个字节而已~

就像前面提到的,内存可以批量,人要计划生育,解耦的目标是为了让程序的可读性增强,进而有助于后续的迭代——有良好结构的代码,带来的不仅仅是人力的节省,也会带来程序的扩展性良好,长期看来,能够实现相同功能的前提下,程序对硬件资源的消耗也会因为良好的设计而减少。

不会有太大的变化,解耦后,将属性和方法都分到不同的类里面,内存使用率不会有太大的变化,即使有,可以忽略不计了。总之,利大于弊,何乐而不为呢。

纯粹为了可读性来把一个class分出新的class,而且新的class的生命周期与原本的class完全一样,则增加memory的耗损。

  • Metaspace/PermGen会变大

  • 原本的class需要记录新的reference value。

当然,这些损耗是很小的。可以忽略。

如果新的类的cohesion更好,而且可以late initialization,那么可以优化内存使用,减少内存损耗。
比如说,

class User {
  private String name;
  private Integer age;
  private String gender;

  private String country;  
  private String address;
  private String zipCode;

  private String companyName;
  private String occupation;
  private String companyAddress;

  private String favoriteSports;
  private String favoriteFoods;
  private String favoriteMovie;
}

任何一个User object就要分配12个fields的内存空间。

split class后,

class User {
  private PersonalInfo personal;
  private Address addr;
  private WorkInfo work;
  private Favorites favorites;
}

首先,初始化User只需要4个reference的内存,不需要初始化12个fields。如果一个用户的favorites是空的,就无需初始化Favorites的内存了。

当然,以上的是很琐碎的东西。真正有价值的是,不必要再把一大托User传来传去,User类驻留内存的时间变短:

//假设有一个module只对WorkInfo有兴趣
class WorkInfoPresentation {
  void displayWorkInfo(String userId) {
    // #L0: 
    final User user = SomeUserDAO.getUser(userId);
    final WorkInfo work = user.getWorkInfo();    
    // #L1: user的生命周期到此为止,可以被Garbage Collect掉了。
    
    callSomeComplicatedHTMLRenderingService(work);
    // #L2: 假设传入的不是work而是user, 那么user的内存就要一直驻留。
  }

  private void callSomeComplicatedHTMLRenderingService(WorkInfo work) {
    // 假定要花很久时间来运算
  }
}

较耗费内存的User的生命周期在#L0 - #L1,而较轻量的WorkInfo的生命周期在#L0 - #L2。User可能在进入callSomeComplicatedHTMLRenderingService之前就被GC掉了,从而节省了#L1 - #L2阶段的内存。

从绝对意义上来说是的,消耗的内存增加了。
但是,对象信息栈和指针上多占一些内存这种消耗是没必要考虑的,就像是
if (a==b){echo a;} 比 if (a==b) echo a; 需要执行更多的指令一样。
随着项目源码的增加、功能的扩展,维护是非常重要的问题,所以不可能丢了西瓜去捡芝麻。解耦对于维护来说价值就是西瓜,消耗的内存就是芝麻(何况还不如芝麻)。

人气教程排行