Skip to content

Commit 0c0d4e5

Browse files
committed
QuickJS: added memory limit check for reuse queue.
1 parent eca0362 commit 0c0d4e5

File tree

4 files changed

+41
-0
lines changed

4 files changed

+41
-0
lines changed

nginx/ngx_http_js_module.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,13 @@ static ngx_command_t ngx_http_js_commands[] = {
433433
offsetof(ngx_http_js_loc_conf_t, reuse),
434434
NULL },
435435

436+
{ ngx_string("js_context_reuse_max_size"),
437+
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
438+
ngx_conf_set_size_slot,
439+
NGX_HTTP_LOC_CONF_OFFSET,
440+
offsetof(ngx_http_js_loc_conf_t, reuse_max_size),
441+
NULL },
442+
436443
{ ngx_string("js_import"),
437444
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE13,
438445
ngx_js_import,

nginx/ngx_js.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,6 +1133,7 @@ ngx_engine_qjs_destroy(ngx_engine_t *e, ngx_js_ctx_t *ctx,
11331133
JSRuntime *rt;
11341134
JSContext *cx;
11351135
JSClassID class_id;
1136+
JSMemoryUsage stats;
11361137
ngx_qjs_event_t *event;
11371138
ngx_js_opaque_t *opaque;
11381139
njs_rbtree_node_t *node;
@@ -1198,6 +1199,28 @@ ngx_engine_qjs_destroy(ngx_engine_t *e, ngx_js_ctx_t *ctx,
11981199
cln->data = conf->reuse_queue;
11991200
}
12001201

1202+
/*
1203+
* After the request object is freed, the runtime's memory usage should
1204+
* be low. It can only remain high if the global scope was
1205+
* modified.
1206+
*
1207+
* To prevent unlimited memory consumption growth, check whether memory
1208+
* usage exceeds the configured limit. The check is performed rarely to
1209+
* avoid performance impact of JS_ComputeMemoryUsage() which is slow.
1210+
*/
1211+
1212+
if ((ngx_random() & 0xff) == 1) {
1213+
JS_ComputeMemoryUsage(JS_GetRuntime(cx), &stats);
1214+
1215+
if ((size_t) stats.malloc_size > conf->reuse_max_size) {
1216+
ngx_log_error(NGX_LOG_WARN, ctx->log, 0,
1217+
"js remaining memory usage of the context "
1218+
"exceeds \"js_context_reuse_max_size\" limit: %L"
1219+
", not reusing it", stats.malloc_size);
1220+
goto free_ctx;
1221+
}
1222+
}
1223+
12011224
if (ngx_js_queue_push(conf->reuse_queue, cx) != NGX_OK) {
12021225
goto free_ctx;
12031226
}
@@ -3950,6 +3973,7 @@ ngx_js_create_conf(ngx_conf_t *cf, size_t size)
39503973
conf->preload_objects = NGX_CONF_UNSET_PTR;
39513974

39523975
conf->reuse = NGX_CONF_UNSET_SIZE;
3976+
conf->reuse_max_size = NGX_CONF_UNSET_SIZE;
39533977
conf->buffer_size = NGX_CONF_UNSET_SIZE;
39543978
conf->max_response_body_size = NGX_CONF_UNSET_SIZE;
39553979
conf->timeout = NGX_CONF_UNSET_MSEC;
@@ -4059,6 +4083,8 @@ ngx_js_merge_conf(ngx_conf_t *cf, void *parent, void *child,
40594083

40604084
ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000);
40614085
ngx_conf_merge_size_value(conf->reuse, prev->reuse, 128);
4086+
ngx_conf_merge_size_value(conf->reuse_max_size, prev->reuse_max_size,
4087+
4 * 1024 * 1024);
40624088
ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, 16384);
40634089
ngx_conf_merge_size_value(conf->max_response_body_size,
40644090
prev->max_response_body_size, 1048576);

nginx/ngx_js.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ typedef struct {
122122
ngx_uint_t type; \
123123
ngx_engine_t *engine; \
124124
ngx_uint_t reuse; \
125+
size_t reuse_max_size; \
125126
ngx_js_queue_t *reuse_queue; \
126127
ngx_str_t cwd; \
127128
ngx_array_t *imports; \

nginx/ngx_stream_js_module.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,13 @@ static ngx_command_t ngx_stream_js_commands[] = {
264264
offsetof(ngx_stream_js_srv_conf_t, reuse),
265265
NULL },
266266

267+
{ ngx_string("js_context_reuse_max_size"),
268+
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
269+
ngx_conf_set_size_slot,
270+
NGX_STREAM_SRV_CONF_OFFSET,
271+
offsetof(ngx_stream_js_srv_conf_t, reuse_max_size),
272+
NULL },
273+
267274
{ ngx_string("js_import"),
268275
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE13,
269276
ngx_js_import,

0 commit comments

Comments
 (0)