首先,我了解"GC 开销限制"错误的含义。我在运行执行以下操作的脚本时收到此消息:
- 创建向外部 API 发出 CFHTTP GET 请求的对象实例
- 将 JSON 响应(数组)存储为对象实例的属性(即 VARIABLES.data)
- 使用
for in
循环遍历 JSON 响应数组 - 在对象上创建一个实例,该实例调用传入 JSON 对象属性的 SQL Server 存储过程(SQL 存储过程根据对象键的记录的存在执行和更新或插入)
调试输出显示 SP 调用需要 3-12 毫秒。
当我使用有限的数据集(~3,000 条记录)运行此脚本时,它会运行完成而不会引发 GC 异常。
当我使用完整的数据集(~14,000 条记录)运行脚本时,会引发 GC 异常。
这是我的伪代码:
for (LOCAL.WidgetJson in VARIABLES.data) {
LOCAL.Widget=new Widget();
LOCAL.Widget
.save(argumentCollection=LOCAL.WidgetJson);
}
Widget.cfc:
private void function saveStoredProc() {
cfstoredproc(procedure="SaveWidget") {
cfprocparam(
dbvarname="@id",
type="in",
cfsqltype="CF_SQL_INT",
value=VARIABLES.id
);
<!--- Rest of cfprocparam() tags here --->
}
private void function save() {
for (LOCAL.Property in ARGUMENTS) {
if (StructKeyExists(ARGUMENTS, LOCAL.Property)) {
if (IsSimpleValue(ARGUMENTS[LOCAL.Property])) {
VARIABLES[LOCAL.Property] = Trim(ARGUMENTS[LOCAL.Property]);
}
else {
VARIABLES[LOCAL.Property] = ARGUMENTS[LOCAL.Property];
}
}
}
saveStoredProc();
}
我想知道是否可以改进我创建对象或循环的方式以防止 GC 异常/内存泄漏。
有什么改进的想法吗?
我认为即使有必要,垃圾收集也不会在单个请求期间发生。您可以增加内存或将其拆分为多个线程来处理较少的数据。