Skip to content

Commit f0b4594

Browse files
committed
feature: added new config directive "lua_malloc_trim N" to periodically call malloc_trim(1) every N requests when malloc_trim() is available.
By default, "lua_malloc_trim 1000" is configured. This should fix the glibc oddity of holding too much freed memory when it fails to use brk() to allocate memory in the data segment.
1 parent 7ecba53 commit f0b4594

File tree

5 files changed

+446
-0
lines changed

5 files changed

+446
-0
lines changed

config

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,24 @@ CC_TEST_FLAGS="-Werror -Wall $CC_TEST_FLAGS"
519519

520520
CC_TEST_FLAGS="$SAVED_CC_TEST_FLAGS"
521521

522+
# ----------------------------------------
523+
524+
ngx_feature="malloc_trim"
525+
ngx_feature_libs=
526+
ngx_feature_name="NGX_HTTP_LUA_HAVE_MALLOC_TRIM"
527+
ngx_feature_run=yes
528+
ngx_feature_incs="#include <malloc.h>
529+
#include <stdio.h>"
530+
ngx_feature_test="int rc = malloc_trim((size_t) 0); printf(\"%d\", rc);"
531+
SAVED_CC_TEST_FLAGS="$CC_TEST_FLAGS"
532+
CC_TEST_FLAGS="-Werror -Wall $CC_TEST_FLAGS"
533+
534+
. auto/feature
535+
536+
CC_TEST_FLAGS="$SAVED_CC_TEST_FLAGS"
537+
538+
# ----------------------------------------
539+
522540
if test -n "$ngx_module_link"; then
523541
ngx_module_type=HTTP_AUX_FILTER
524542
ngx_module_name=$ngx_addon_name

src/ngx_http_lua_common.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,10 @@ struct ngx_http_lua_main_conf_s {
193193

194194
ngx_http_lua_sema_mm_t *sema_mm;
195195

196+
ngx_uint_t malloc_trim_cycle; /* a cycle is defined as the number
197+
of reqeusts */
198+
ngx_uint_t malloc_trim_req_count;
199+
196200
unsigned requires_header_filter:1;
197201
unsigned requires_body_filter:1;
198202
unsigned requires_capture_filter:1;

src/ngx_http_lua_logby.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
#include "ngx_http_lua_shdict.h"
2828
#include "ngx_http_lua_util.h"
2929
#include "ngx_http_lua_exception.h"
30+
#if NGX_HTTP_LUA_HAVE_MALLOC_TRIM
31+
#include <malloc.h>
32+
#endif
3033

3134

3235
static ngx_int_t ngx_http_lua_log_by_chunk(lua_State *L, ngx_http_request_t *r);
@@ -67,9 +70,39 @@ ngx_http_lua_log_by_lua_env(lua_State *L, ngx_http_request_t *r)
6770
ngx_int_t
6871
ngx_http_lua_log_handler(ngx_http_request_t *r)
6972
{
73+
#if NGX_HTTP_LUA_HAVE_MALLOC_TRIM
74+
ngx_uint_t trim_cycle, trim_nreq;
75+
#endif
76+
ngx_http_lua_main_conf_t *lmcf;
7077
ngx_http_lua_loc_conf_t *llcf;
7178
ngx_http_lua_ctx_t *ctx;
7279

80+
lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
81+
82+
#if NGX_HTTP_LUA_HAVE_MALLOC_TRIM
83+
trim_cycle = lmcf->malloc_trim_cycle;
84+
85+
if (trim_cycle > 0) {
86+
87+
dd("cycle: %d", (int) trim_cycle);
88+
89+
trim_nreq = ++lmcf->malloc_trim_req_count;
90+
91+
if (trim_nreq >= trim_cycle) {
92+
lmcf->malloc_trim_req_count = 0;
93+
94+
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
95+
"malloc_trim(1) returned %d", malloc_trim(1));
96+
}
97+
}
98+
# if (NGX_DEBUG)
99+
else {
100+
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
101+
"malloc_trim() disabled");
102+
}
103+
# endif
104+
#endif
105+
73106
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
74107
"lua log handler, uri:\"%V\" c:%ud", &r->uri,
75108
r->main->count);

src/ngx_http_lua_module.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ void ngx_http_lua_limit_data_segment(void);
5353
static ngx_int_t ngx_http_lua_pre_config(ngx_conf_t *cf);
5454
# endif
5555
#endif
56+
static char *ngx_http_lua_malloc_trim(ngx_conf_t *cf, ngx_command_t *cmd,
57+
void *conf);
5658

5759

5860
static ngx_conf_post_t ngx_http_lua_lowat_post =
@@ -578,6 +580,13 @@ static ngx_command_t ngx_http_lua_cmds[] = {
578580

579581
#endif /* NGX_HTTP_SSL */
580582

583+
{ ngx_string("lua_malloc_trim"),
584+
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
585+
ngx_http_lua_malloc_trim,
586+
NGX_HTTP_MAIN_CONF_OFFSET,
587+
0,
588+
NULL },
589+
581590
ngx_null_command
582591
};
583592

@@ -832,6 +841,10 @@ ngx_http_lua_create_main_conf(ngx_conf_t *cf)
832841
lmcf->postponed_to_rewrite_phase_end = NGX_CONF_UNSET;
833842
lmcf->postponed_to_access_phase_end = NGX_CONF_UNSET;
834843

844+
#if (NGX_HTTP_LUA_HAVE_MALLOC_TRIM)
845+
lmcf->malloc_trim_cycle = NGX_CONF_UNSET_UINT;
846+
#endif
847+
835848
#ifndef NGX_LUA_NO_FFI_API
836849
rc = ngx_http_lua_sema_mm_init(cf, lmcf);
837850
if (rc != NGX_OK) {
@@ -868,6 +881,12 @@ ngx_http_lua_init_main_conf(ngx_conf_t *cf, void *conf)
868881
lmcf->max_running_timers = 256;
869882
}
870883

884+
#if (NGX_HTTP_LUA_HAVE_MALLOC_TRIM)
885+
if (lmcf->malloc_trim_cycle == NGX_CONF_UNSET_UINT) {
886+
lmcf->malloc_trim_cycle = 1000; /* number of reqs */
887+
}
888+
#endif
889+
871890
lmcf->cycle = cf->cycle;
872891

873892
return NGX_CONF_OK;
@@ -1283,4 +1302,39 @@ ngx_http_lua_limit_data_segment(void)
12831302
}
12841303
#endif
12851304

1305+
1306+
static char *
1307+
ngx_http_lua_malloc_trim(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1308+
{
1309+
#if NGX_HTTP_LUA_HAVE_MALLOC_TRIM
1310+
1311+
ngx_int_t nreqs;
1312+
ngx_str_t *value;
1313+
1314+
ngx_http_lua_main_conf_t *lmcf = conf;
1315+
1316+
value = cf->args->elts;
1317+
1318+
nreqs = ngx_atoi(value[1].data, value[1].len);
1319+
if (nreqs == NGX_ERROR) {
1320+
return "invalid number in the 1st argument";
1321+
}
1322+
1323+
lmcf->malloc_trim_cycle = (ngx_uint_t) nreqs;
1324+
1325+
if (nreqs == 0) {
1326+
return NGX_CONF_OK;
1327+
}
1328+
1329+
lmcf->requires_log = 1;
1330+
1331+
#else
1332+
1333+
ngx_conf_log_error(NGX_LOG_WARN, cf, 0, "lua_malloc_trim is not supported "
1334+
"on this platform, ignored");
1335+
1336+
#endif
1337+
return NGX_CONF_OK;
1338+
}
1339+
12861340
/* vi:set ft=c ts=4 sw=4 et fdm=marker: */

0 commit comments

Comments
 (0)