diff --git a/configure b/configure
index 732f6ca455e7b635cca98f7f2a2bad344464ce29..c4920e94d164ae449700fa73a141d2f0f150853c 100755
--- a/configure
+++ b/configure
@@ -16750,7 +16750,7 @@ fi
 done
 
 
-for ac_func in asprintf atexit closefrom dup2 eaccess endpwent euidaccess ffsll ftruncate getcwd gethostbyname gethostname getloadavg gettimeofday glob ioperm inet_ntoa isascii memchr memmove memset mkdir mkdtemp munmap newlocale ppoll putenv re_comp regcomp select setenv socket strcasecmp strcasestr strchr strcspn strdup strerror strlcat strlcpy strncasecmp strndup strnlen strrchr strsep strspn strstr strtod strtol strtold strtoq unsetenv uselocale utime vasprintf getpeereid sysctl swapctl
+for ac_func in asprintf atexit closefrom dup2 eaccess endpwent euidaccess ffsll ftruncate getcwd gethostbyname gethostname getloadavg gettimeofday glob ioperm inet_ntoa isascii memchr memmove memset mkdir mkdtemp munmap newlocale ppoll putenv re_comp regcomp select setenv socket strcasecmp strcasestr strchr strcspn strdup strerror strlcat strlcpy strncasecmp strndup strnlen strrchr strsep strspn strstr strtod strtol strtold strtoq unsetenv uselocale utime vasprintf getpeereid sysctl swapctl malloc_trim
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
diff --git a/configure.ac b/configure.ac
index 46f62b89aad199934a47169f00dad4ae70be0fca..11b8dc9c35eb61d63c2fbc4d99ddb7e153165a49 100644
--- a/configure.ac
+++ b/configure.ac
@@ -761,7 +761,7 @@ AC_FUNC_STRNLEN
 AC_FUNC_STRTOD
 AC_FUNC_UTIME_NULL
 AC_FUNC_VPRINTF
-AC_CHECK_FUNCS([asprintf atexit closefrom dup2 eaccess endpwent euidaccess ffsll ftruncate getcwd gethostbyname gethostname getloadavg gettimeofday glob ioperm inet_ntoa isascii memchr memmove memset mkdir mkdtemp munmap newlocale ppoll putenv re_comp regcomp select setenv socket strcasecmp strcasestr strchr strcspn strdup strerror strlcat strlcpy strncasecmp strndup strnlen strrchr strsep strspn strstr strtod strtol strtold strtoq unsetenv uselocale utime vasprintf getpeereid sysctl swapctl])
+AC_CHECK_FUNCS([asprintf atexit closefrom dup2 eaccess endpwent euidaccess ffsll ftruncate getcwd gethostbyname gethostname getloadavg gettimeofday glob ioperm inet_ntoa isascii memchr memmove memset mkdir mkdtemp munmap newlocale ppoll putenv re_comp regcomp select setenv socket strcasecmp strcasestr strchr strcspn strdup strerror strlcat strlcpy strncasecmp strndup strnlen strrchr strsep strspn strstr strtod strtol strtold strtoq unsetenv uselocale utime vasprintf getpeereid sysctl swapctl malloc_trim])
 
 AC_MSG_CHECKING(for htonll)
 AC_LINK_IFELSE(
diff --git a/include/asterisk/autoconfig.h.in b/include/asterisk/autoconfig.h.in
index 0fa2859cb41428fdd78fe431fe699683583d5cb0..22daea0f7cc9e0b2b6dd07d16a490a3c2f780aab 100644
--- a/include/asterisk/autoconfig.h.in
+++ b/include/asterisk/autoconfig.h.in
@@ -462,6 +462,9 @@
 /* Define to 1 if you have the <malloc.h> header file. */
 #undef HAVE_MALLOC_H
 
+/* Define to 1 if you have the `malloc_trim' function. */
+#undef HAVE_MALLOC_TRIM
+
 /* Define to 1 if you have the `memchr' function. */
 #undef HAVE_MEMCHR
 
diff --git a/main/cli.c b/main/cli.c
index dc75acb1288872d53e32fb861e85c89fbde7fd33..f980fc6397633d4a4d810c5e679d2dd603822ca3 100644
--- a/main/cli.c
+++ b/main/cli.c
@@ -1791,6 +1791,34 @@ static char *handle_cli_wait_fullybooted(struct ast_cli_entry *e, int cmd, struc
 	return CLI_SUCCESS;
 }
 
+
+#ifdef HAVE_MALLOC_TRIM
+	/* BUGBUG malloc_trim() is a libc specific function.  Non-portable. */
+	static char *handle_cli_malloc_trim(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+	{
+		extern int malloc_trim(size_t __pad) __THROW;
+
+		switch (cmd) {
+		case CLI_INIT:
+			e->command = "malloc trim";
+			e->usage =
+				"Usage: malloc trim\n"
+				"       Try to give excess memory back to the OS.\n";
+			return NULL;
+		case CLI_GENERATE:
+			return NULL;
+		}
+
+		if (malloc_trim(0)) {
+			ast_cli(a->fd, "Returned some memory to the OS.\n");
+		} else {
+			ast_cli(a->fd, "No memory returned to the OS.\n");
+		}
+
+		return CLI_SUCCESS;
+	}
+#endif
+
 static char *handle_help(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
 
 static struct ast_cli_entry cli_cli[] = {
@@ -1837,6 +1865,11 @@ static struct ast_cli_entry cli_cli[] = {
 	AST_CLI_DEFINE(handle_cli_check_permissions, "Try a permissions config for a user"),
 
 	AST_CLI_DEFINE(handle_cli_wait_fullybooted, "Wait for Asterisk to be fully booted"),
+
+#ifdef HAVE_MALLOC_TRIM
+	AST_CLI_DEFINE(handle_cli_malloc_trim, "Return excess memory to the OS"),
+#endif
+
 };
 
 /*!