]> git.sur5r.net Git - bacula/bacula/commitdiff
Add code to trim heap after big mallocs
authorKern Sibbald <kern@sibbald.com>
Thu, 3 Feb 2011 10:44:35 +0000 (11:44 +0100)
committerKern Sibbald <kern@sibbald.com>
Thu, 3 Feb 2011 11:03:47 +0000 (12:03 +0100)
bacula/autoconf/config.h.in
bacula/autoconf/configure.in
bacula/src/dird/ua_cmds.c
bacula/src/dird/ua_restore.c
bacula/src/lib/bnet.c
bacula/src/lib/bsock.c
bacula/src/lib/htable.c
bacula/src/lib/jcr.c
bacula/src/lib/mem_pool.c
bacula/src/lib/mem_pool.h
bacula/src/lib/tree.c

index ecb138732d8a9b3212b82bc7ece1aca3626ad4ad..2fb4214085c0c1dabfb30c3e5a9edfc46c8a554c 100644 (file)
 /* Define to 1 if you have the <malloc.h> header file. */
 #undef HAVE_MALLOC_H
 
+/* Set if have malloc_trim */
+#undef HAVE_MALLOC_TRIM
+
 /* Define to 1 if you have the <memory.h> header file. */
 #undef HAVE_MEMORY_H
 
index af0a07cb592499f07a191295cc1f075345b6610a..302a47cd8f6e75ccca66a303961ddc64e449027b 100644 (file)
@@ -2398,6 +2398,8 @@ AC_CHECK_FUNCS( \
    [echo 'configure: cannot find needed function.'; exit 1]
 )
 
+AC_CHECK_FUNCS(malloc_trim, [AC_DEFINE(HAVE_MALLOC_TRIM, 1, [Set if have malloc_trim])])
+
 AC_CHECK_FUNCS(fchdir, [AC_DEFINE(HAVE_FCHDIR)])
 AC_CHECK_FUNCS(strtoll, [AC_DEFINE(HAVE_STRTOLL)])
 AC_CHECK_FUNCS(posix_fadvise)
index e1a9cb11ce99713a0dc3be7f6dbf2728ac830dec..1988ff10db55e16533aba9c6e99f40019dfa77b8 100644 (file)
@@ -1553,6 +1553,7 @@ static int delete_pool(UAContext *ua)
 
 int memory_cmd(UAContext *ua, const char *cmd)
 {
+   garbage_collect_memory();
    list_dir_status_header(ua);
    sm_dump(false, true);
    return 1;
index e460ac5c25c1a1ee6bd4c18bb1b85a7668fba540..49176f92fd281b2a7226ffa1cf3cdecf911df322 100644 (file)
@@ -294,7 +294,7 @@ int restore_cmd(UAContext *ua, const char *cmd)
    parse_ua_args(ua);
    run_cmd(ua, ua->cmd);
    free_rx(&rx);
-   close_memory_pool();            /* release freed pool memory */
+   garbage_collect_memory();       /* release unused memory */
    return 1;
 
 bail_out:
@@ -311,7 +311,7 @@ bail_out:
    }
 
    free_rx(&rx);
-   close_memory_pool();            /* release freed pool memory */
+   garbage_collect_memory();       /* release unused memory */
    return 0;
 
 }
@@ -1165,6 +1165,13 @@ static bool build_directory_tree(UAContext *ua, RESTORE_CTX *rx)
       }
    }
 #endif
+   /* 
+    * At this point, the tree is built, so we can garbage collect
+    * any memory released by the SQL engine that RedHat has 
+    * not returned to the OS :-( 
+    */
+    garbage_collect_memory();
+
    /*
     * Look at the first JobId on the list (presumably the oldest) and
     *  if it is marked purged, don't do the manual selection because
index 851197a981138eb4c2e31bdd45778c0ae685c364..e141767134853ae592e871001f12b56759f612c0 100644 (file)
@@ -681,7 +681,7 @@ BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int
    bsock->tls = NULL;
    bsock->errors = 0;
    bsock->m_blocking = 1;
-   bsock->msg = get_pool_memory(PM_MESSAGE);
+   bsock->msg = get_pool_memory(PM_BSOCK);
    bsock->errmsg = get_pool_memory(PM_MESSAGE);
    bsock->set_who(bstrdup(who));
    bsock->set_host(bstrdup(host));
@@ -701,7 +701,7 @@ BSOCK *dup_bsock(BSOCK *osock)
 {
    BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
    memcpy(bsock, osock, sizeof(BSOCK));
-   bsock->msg = get_pool_memory(PM_MESSAGE);
+   bsock->msg = get_pool_memory(PM_BSOCK);
    bsock->errmsg = get_pool_memory(PM_MESSAGE);
    if (osock->who()) {
       bsock->set_who(bstrdup(osock->who()));
index f9fa8fbccd5e280bf56dcdbc34a936ccc8700f0d..b1550c14b3627d21dd50e0d01b4ec63ef08126dd 100644 (file)
@@ -66,7 +66,7 @@ void BSOCK::init()
 {
    memset(this, 0, sizeof(BSOCK));
    m_blocking = 1;
-   msg = get_pool_memory(PM_MESSAGE);
+   msg = get_pool_memory(PM_BSOCK);
    errmsg = get_pool_memory(PM_MESSAGE);
    /*
     * ****FIXME**** reduce this to a few hours once
index a42ec022d0c82e5d30156a1ae70deeeb90cc3dd7..eaa057d0d9578000931c9cd5584c73888a966024 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2003-2010 Free Software Foundation Europe e.V.
+   Copyright (C) 2003-2011 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
@@ -371,6 +371,7 @@ void htable::destroy()
 
    free(table);
    table = NULL;
+   garbage_collect_memory();
    Dmsg0(100, "Done destroy.\n");
 }
 
index 5b88efdc35fe94a765bc957f603f305a1deec98d..0f63c0807e1bf37497900fe27dad3f308ec04d0e 100644 (file)
@@ -576,7 +576,6 @@ void free_jcr(JCR *jcr)
 
    free_common_jcr(jcr);
    close_msg(NULL);                   /* flush any daemon messages */
-   garbage_collect_memory_pool();
    Dmsg0(dbglvl, "Exit free_jcr\n");
 }
 
index a371fdd737f746b5dbbc1cef0064bfbdc251d435..575b4868e276ec608bdc01a6d4559884ea624b43 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2010 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
@@ -47,6 +47,9 @@
  */
 
 #include "bacula.h"
+#ifdef HAVE_MALLOC_TRIM
+#include <malloc.h>
+#endif
 
 struct s_pool_ctl {
    int32_t size;                      /* default size */
@@ -69,7 +72,8 @@ static struct s_pool_ctl pool_ctl[] = {
    {  NLEN, NLEN,0, 0, NULL },        /* PM_NAME Bacula name */
    {  256,  256, 0, 0, NULL },        /* PM_FNAME filename buffers */
    {  512,  512, 0, 0, NULL },        /* PM_MESSAGE message buffer */
-   { 1024, 1024, 0, 0, NULL }         /* PM_EMSG error message buffer */
+   { 1024, 1024, 0, 0, NULL },        /* PM_EMSG error message buffer */
+  {  4096, 4096, 0, 0, NULL }         /* PM_BSOCK message buffer */
 };
 #else
 
@@ -79,7 +83,8 @@ static struct s_pool_ctl pool_ctl[] = {
    {  NLEN, NLEN,0, 0, NULL },        /* PM_NAME Bacula name */
    {   20,   20, 0, 0, NULL },        /* PM_FNAME filename buffers */
    {   20,   20, 0, 0, NULL },        /* PM_MESSAGE message buffer */
-   {   20,   20, 0, 0, NULL }         /* PM_EMSG error message buffer */
+   {   20,   20, 0, 0, NULL },        /* PM_EMSG error message buffer */
+   {   20,   20, 0, 0, NULL }         /* PM_BSOCK message buffer */
 };
 #endif
 
@@ -377,13 +382,13 @@ void garbage_collect_memory_pool()
    if (now >= last_garbage_collection + garbage_interval) {
       last_garbage_collection = now;
       V(mutex);
-      close_memory_pool();
+      garbage_collect_memory();
    } else {
       V(mutex);
    }
 }
 
-/* Release all pooled memory */
+/* Release all freed pooled memory */
 void close_memory_pool()
 {
    struct abufhead *buf, *next;
@@ -412,6 +417,21 @@ void close_memory_pool()
 
 }
 
+/*
+ * Garbage collect and trim memory if possible
+ *  This should be called after all big memory usages
+ *  if possible.
+ */
+void garbage_collect_memory()
+{
+   close_memory_pool();         /* release free chain */
+#ifdef HAVE_MALLOC_TRIM
+   P(mutex);
+   malloc_trim(8192);
+   V(mutex);
+#endif
+}
+
 #ifdef DEBUG
 static const char *pool_name(int pool)
 {
index 626bf22fc19532d119a99be63548da93de252441..c1a2f4d998c2184bf0d24688be137687ba4df587 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2010 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
@@ -76,6 +76,7 @@ extern void garbage_collect_memory_pool();
 extern void  close_memory_pool();
 extern void  print_memory_pool_stats();
 
+extern void garbage_collect_memory();
 
 
 #define PM_NOPOOL  0                  /* nonpooled memory */
@@ -83,7 +84,8 @@ extern void  print_memory_pool_stats();
 #define PM_FNAME   2                  /* file name buffer */
 #define PM_MESSAGE 3                  /* daemon message */
 #define PM_EMSG    4                  /* error message */
-#define PM_MAX     PM_EMSG            /* Number of types */
+#define PM_BSOCK   5                  /* BSOCK buffer */
+#define PM_MAX     PM_BSOCK           /* Number of types */
 
 class POOL_MEM {
    char *mem;
index f9fc4ac88613e6051f7b6769b1296f5d0e671bc6..fda5b0a72ca5d5a84cd31d4e1eaccdb4cfd82db7 100644 (file)
@@ -184,6 +184,7 @@ void free_tree(TREE_ROOT *root)
    }
    Dmsg3(100, "Total size=%u blocks=%u freed_blocks=%u\n", root->total_size, root->blocks, freed_blocks);
    free(root);
+   garbage_collect_memory();
    return;
 }