有一段时间我有一个理论,即在每个请求上实例化对象而不是让它们驻留在Application范围内是一个巨大的记忆力。由于我多年来对ColdFusion的了解不断增长,我不认为我真的理解CF如何处理"黑盒子中的课程。 CF框架,所以我要问这个社区更正或确认。
我只是要抛弃我认为正在发生的事情:
这消除了我个人可能多年来所听到的巨大谬误,即在每个请求中实例化大型对象都是一次巨大的记忆困扰(由于拥有该类的副本而不仅仅是参考)。请注意,我并不赞成这一点,单身模式令人惊叹。我只是想确认一下发生了什么,以防止在遗留代码中追逐红色鲱鱼。
编辑:感谢大家的投入,这对我来说真的很有帮助。
答案 0 :(得分:23)
我已经开发了14年的CF并且我从未听过有人声称由于类编译而在每个请求上创建CFC实例消耗了内存。在Java级别,您的CFML代码直接编译为字节码,并作为Java类存储在内存和磁盘上。 Java类不存储在堆中,而是存储在永久生成中,而不是(通常)收集的内存空间。您可以创建该CFC的任意数量的实例,并且不会再使用perm gen空间,但是将分配堆空间以在其存在的持续时间内存储该CFC的实例数据。注意,开源Railo不为方法使用单独的类。
现在,如果你为这个问题创建了大量的CFC实例(或任何变量),那将会在你们年轻一代中产生很多瑕疵。只要在请求完成后没有保留硬引用,那么当下一个次要垃圾收集运行时,这些对象将从堆中清除。这不一定是坏事,但在调整应用程序性能时应始终考虑堆大小和GC暂停。
现在,有理由坚持CFC实例,无论是作为单例模式还是在会话,请求等的持续时间内。一个原因是实际对象创建的开销。这通常涉及磁盘I / O以检查上次修改时间。自从过去以来,对象创建的速度显着提高,但如果您要创建数千个实例,它仍远远落后于原生Java。另一个主要原因是您的对象在应用程序/会话/请求的生命周期内保持状态,例如在用户购物时存储在会话中的购物车。
为了完整起见,我将尝试明确地解决您的观点: