仅当值代表某个对象的状态时,将值作为字段才有意义。
我想知道在某些情况下是否应该避免这个“规则”。
这是一个例子,假设这个类:
public class DbCar {
private ResultSet rs;
public DbMapper(ResultSet rs) {
this.rs = rs;
}
public Car buildObject(){
//.....does some mappings, then returns the builded car ....
}
}
Run Code Online (Sandbox Code Playgroud)
因此,我们看到 ResultSet 被存储为成员变量,这是有意义的,因为每个 DbMapper(如 DbCar)都操作从 JDBC 查询检索到的 ResultSet。
我们会有一个如下所示的调用者:
while (rs.next()) {
items.add(new DbCar(rs)).buildObject();
}
Run Code Online (Sandbox Code Playgroud)
但假设当前查询返回 15000 条记录。
简而言之 => 创建了 15000 个 DbCar 对象实例。
所以我的问题是:垃圾收集器是否足够高效,以便我不必担心如此大量的实例?
当然,为了避免所有这些情况,我们可以重构代码如下:
public class DbCar {
public Car buildObject(ResultSet rs) {
//.....does some mappings, then returns the builded car ....
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,将创建 DbCar 的单个实例(在当前线程和当前方法中),调用者如下所示:
DbCar dbCar = new DbCar();
while (rs.next()) {
items.add(dbCar.buildObject(rs));
}
Run Code Online (Sandbox Code Playgroud)
那么,我应该选择哪种解决方案?相信垃圾收集器具有更优雅的代码或像具有本地参数方法的更过程化编码风格的编码?
为了让选择变得更加困难,想象一下 DbCar 类将其“构建”方法划分为优雅的小方法,每个方法专门负责特定的职责,例如:
“buildEngine”、“buildDoors”等...如果选择本地参数,我必须将 ResultSet 传递到所有这些方法中...无聊且重复,不是吗?
这对于 GC 来说并不构成问题,但这一切都归结为您的应用程序要求。
在之前的项目中,我参与开发了一个非常大的“近实时”应用程序,该应用程序在 Solaris 服务器上运行(需要 10GB RAM 才能启动),该应用程序大约每 4 秒左右创建 150000 个 DTO 对象。乍一看这对 GC 没有影响,但经过一些工作时间后,用户开始抱怨软件丢失了来自硬件的数据。我们花了一个漫长的夜晚调查这个问题,最终发现 GC 占用了全部 CPU 来清理未使用的对象,这使得应用程序看起来挂起了一秒钟左右(相信我,一秒钟的数据丢失成本会更高)超过 1000 美元)
| 归档时间: |
|
| 查看次数: |
263 次 |
| 最近记录: |