2015-12-30 04:52:24 -05:00
|
|
|
(* Copyright (C) 2015, Thomas Leonard <thomas.leonard@unikernel.com>
|
|
|
|
See the README file for details. *)
|
|
|
|
|
2016-01-02 10:59:59 -05:00
|
|
|
open Lwt
|
|
|
|
|
|
|
|
let src = Logs.Src.create "memory_pressure" ~doc:"Memory pressure monitor"
|
|
|
|
module Log = (val Logs.src_log src : Logs.LOG)
|
|
|
|
|
2020-08-19 09:09:01 -04:00
|
|
|
let wordsize_in_bytes = Sys.word_size / 8
|
|
|
|
|
|
|
|
let fraction_free stats =
|
2022-03-30 03:12:01 -04:00
|
|
|
let { Xen_os.Memory.free_words; heap_words; _ } = stats in
|
2020-08-19 09:09:01 -04:00
|
|
|
float free_words /. float heap_words
|
|
|
|
|
|
|
|
let meminfo stats =
|
2022-03-30 03:12:01 -04:00
|
|
|
let { Xen_os.Memory.free_words; heap_words; _ } = stats in
|
2020-08-19 09:09:01 -04:00
|
|
|
let mem_total = heap_words * wordsize_in_bytes in
|
|
|
|
let mem_free = free_words * wordsize_in_bytes in
|
|
|
|
Log.info (fun f -> f "Writing meminfo: free %a / %a (%.2f %%)"
|
|
|
|
Fmt.bi_byte_size mem_free
|
|
|
|
Fmt.bi_byte_size mem_total
|
|
|
|
(fraction_free stats *. 100.0));
|
2016-01-02 10:59:59 -05:00
|
|
|
Printf.sprintf "MemTotal: %d kB\n\
|
|
|
|
MemFree: %d kB\n\
|
|
|
|
Buffers: 0 kB\n\
|
|
|
|
Cached: 0 kB\n\
|
|
|
|
SwapTotal: 0 kB\n\
|
2020-08-19 09:09:01 -04:00
|
|
|
SwapFree: 0 kB\n" (mem_total / 1024) (mem_free / 1024)
|
2016-01-02 10:59:59 -05:00
|
|
|
|
|
|
|
let init () =
|
2023-05-26 04:27:29 -04:00
|
|
|
Gc.full_major ()
|
2015-12-30 04:52:24 -05:00
|
|
|
|
|
|
|
let status () =
|
2022-03-30 03:12:01 -04:00
|
|
|
let stats = Xen_os.Memory.quick_stat () in
|
2022-09-05 04:01:15 -04:00
|
|
|
if fraction_free stats > 0.5 then `Ok
|
2015-12-30 04:52:24 -05:00
|
|
|
else (
|
|
|
|
Gc.full_major ();
|
2022-07-27 08:26:58 -04:00
|
|
|
Xen_os.Memory.trim ();
|
2022-03-30 03:12:01 -04:00
|
|
|
let stats = Xen_os.Memory.quick_stat () in
|
2023-05-26 04:27:29 -04:00
|
|
|
if fraction_free stats < 0.6 then `Memory_critical
|
|
|
|
else `Ok
|
2015-12-30 04:52:24 -05:00
|
|
|
)
|