1 /** 2 Copyright: Copyright (c) 2020, Joakim Brännström. All rights reserved. 3 License: MPL-2 4 Author: Joakim Brännström (joakim.brannstrom@gmx.com) 5 6 This Source Code Form is subject to the terms of the Mozilla Public License, 7 v.2.0. If a copy of the MPL was not distributed with this file, You can obtain 8 one at http://mozilla.org/MPL/2.0/. 9 */ 10 module dextool.gc; 11 12 import std.concurrency; 13 import std.datetime : SysTime, Clock, dur; 14 15 /** Reduces the used memory by the GC and free the heap to the OS. 16 * 17 * To avoid calling this too often the struct have a timer to ensure it is 18 * callled at most ones every minute. 19 * 20 * TODO: maybe add functionality to call it more often when above e.g. 50% memory usage? 21 */ 22 struct MemFree { 23 private { 24 bool isRunning; 25 Tid bg; 26 } 27 28 ~this() @trusted { 29 if (!isRunning) 30 return; 31 scope (exit) 32 isRunning = false; 33 send(bg, Msg.stop); 34 } 35 36 /** Start a background thread to do the work. 37 * 38 * It terminates when the destructor is called. 39 */ 40 void start() @trusted { 41 scope (success) 42 isRunning = true; 43 bg = spawn(&tick); 44 } 45 46 } 47 48 private: 49 50 enum Msg { 51 stop, 52 } 53 54 void tick() nothrow { 55 import core.thread : Thread; 56 import core.time : dur; 57 import core.memory : GC; 58 59 const tickInterval = 1.dur!"minutes"; 60 61 bool running = true; 62 SysTime next = Clock.currTime + tickInterval; 63 while (running) { 64 try { 65 receiveTimeout(tickInterval, (Msg x) { running = false; }); 66 } catch (Exception e) { 67 running = false; 68 } 69 70 GC.collect; 71 GC.minimize; 72 malloc_trim(0); 73 } 74 } 75 76 // malloc_trim - release free memory from the heap 77 extern (C) int malloc_trim(size_t pad) nothrow @system;