不可变对象如何帮助减少垃圾回收带来的开销?
2022-09-01 15:36:26
有时,当对象不可变时,分配较少。
简单示例
Date getDate(){
return copy(this.date);
}
每次共享它时,我都必须复制它,因为它是可变的,否则调用方将能够改变它。如果被叫了很多,分配率将急剧增加,这将给Date
getDate
GC
另一方面,Java-8日期是不可变的。
LocalDate getDate(){
return this.date;
}
请注意,由于不可变性,我不需要复制日期(分配新对象)(我很高兴与您共享该对象,因为我知道您无法更改它)。
现在你可能会想,我怎么能把它应用到“有用”或复杂的数据结构中,而不会造成大量的分配(由于防御性副本),你是绝对正确的,但是有一种艺术叫做和(即:你得到的错觉是它是一个新的副本,实际上副本与原始副本共享很多)。functional programming
persistent data structures
人们不应该感到惊讶的是,大多数函数式语言(我所知道的所有函数式语言)都是垃圾收集的。
不可变对象不需要防御性副本,如果您跨上下文共享它们(例如调用您不信任的代码)或线程安全。这可能意味着不可变对象的读取量在垃圾方面可能会降低。
另一方面,每次更改不可变对象时,无论是否需要创建新对象,都必须创建新对象。在这方面,不可变对象可以创建更多的垃圾。
真正的问题是你是进行大量读取,还是大量写入(或混合),根据用途,不可变对象可以保存对象或创建更多对象,因此根据您的特定用例使用不可变对象或可变对象是有意义的。
注意:大多数时候,正确性远比性能重要得多,虽然恕我直言,一般来说,不可变对象具有更高的开销,但使用不可变对象证明数据模型的正确性要容易得多,并且值得使用不可变对象来简化推理。