一个类解耦成多个类,从实例化一个类到要实例化多个类,这样是不是增加了内存的消耗?
一个类解耦成多个类,从实例化一个类到要实例化多个类,这样是不是增加了内存的消耗?
回复内容:
一个类解耦成多个类,从实例化一个类到要实例化多个类,这样是不是增加了内存的消耗?
如果解耦得当,基本不会增加内存消耗,因为对象中的方法和参数虽然被分成到了不同的类中,但每个方法和参数占用空间都没有变,所有总体内存也没有变。只是在对象信息栈和指针上多占一些内存,不过这些基本都是可以忽略的。
内存可以批量生产,人要计划生育
如果所有用到这一个类的地方,都需要实例化解耦后的所有类,那这个类就没有必要解耦
是
但人工比内存贵得多
就单从语义来看,这是肯定的。
但是内存的消耗只是开发的一部分,毕竟还要考虑开发成本,维护成本
看起来没有太大的差别,只是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; 需要执行更多的指令一样。
随着项目源码的增加、功能的扩展,维护是非常重要的问题,所以不可能丢了西瓜去捡芝麻。解耦对于维护来说价值就是西瓜,消耗的内存就是芝麻(何况还不如芝麻)。