Skip to content

Commit

Permalink
Add private and swapped process memory.
Browse files Browse the repository at this point in the history
  • Loading branch information
toots committed Apr 17, 2024
1 parent a415a38 commit 16e142f
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 9 deletions.
2 changes: 1 addition & 1 deletion .ocamlformat
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version=0.19.0
version=0.25.1
profile = conventional
break-separators = after
space-around-lists = false
Expand Down
4 changes: 4 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
0.1.1 (unreleased)
=====
* Added private and swapped process memory.

0.1.0 (2024-01-31)
======
* Widen memory size integers (#4)
Expand Down
84 changes: 78 additions & 6 deletions lib/mem_usage.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ CAMLprim value ocaml_mem_usage_mem_usage(value unit) {
CAMLparam0();
CAMLlocal1(ret);
MEMORYSTATUSEX mem_info;
PROCESS_MEMORY_COUNTERS_EX pmc;
PROCESS_MEMORY_COUNTERS_EX2 pmc;
DWORDLONG total_virtual_memory;
DWORDLONG total_used_virtual_memory;
DWORDLONG total_physical_memory;
DWORDLONG total_used_physical_memory;
SIZE_T process_virtual_memory;
SIZE_T process_physical_memory;
SIZE_T process_private_memory;
SIZE_T process_swapped_memory;

caml_release_runtime_system();
mem_info.dwLength = sizeof(MEMORYSTATUSEX);
Expand All @@ -38,34 +40,68 @@ CAMLprim value ocaml_mem_usage_mem_usage(value unit) {
sizeof(pmc));
process_virtual_memory = pmc.PrivateUsage;
process_physical_memory = pmc.WorkingSetSize;
process_private_memory = pmc.PrivateWorkingSetSize;
process_swapped_memory = pmc.PagefileUsage;
caml_acquire_runtime_system();

ret = caml_alloc_tuple(6);
ret = caml_alloc_tuple(8);
Store_field(ret, 0, Val_long(total_virtual_memory));
Store_field(ret, 1, Val_long(total_physical_memory));
Store_field(ret, 2, Val_long(total_used_virtual_memory));
Store_field(ret, 3, Val_long(total_used_physical_memory));
Store_field(ret, 4, Val_long(process_virtual_memory));
Store_field(ret, 5, Val_long(process_physical_memory));
Store_Field(ret, 6, Val_long(process_private_memory));
Store_Field(ret, 7, Val_long(process_swapped_memory));
CAMLreturn(ret);
}
#elif defined(__APPLE__)
#include <mach/mach.h>
#include <mach/mach_host.h>
#include <mach/mach_init.h>
#include <mach/mach_types.h>
#include <mach/mach_vm.h>
#include <mach/vm_statistics.h>
#include <stdio.h>
#include <sys/mount.h>
#include <sys/sysctl.h>
#include <unistd.h>

void private_pages(unsigned int *pages_resident,
unsigned int *pages_swapped_out) {
mach_vm_address_t address = 0;
mach_vm_size_t size = 0;
uint32_t depth = 2048;
vm_region_submap_info_data_64_t info;
mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT_64;
kern_return_t kr;
*pages_resident = 0;
*pages_swapped_out = 0;

while (1) {
kr = mach_vm_region_recurse(mach_task_self(), &address, &size, &depth,
(vm_region_recurse_info_t)&info, &count);

if (kr != KERN_SUCCESS || size == 0)
break;

if (info.share_mode == SM_PRIVATE) {
*pages_resident += info.pages_resident;
*pages_swapped_out += info.pages_swapped_out;
}

address += size;
}
}

CAMLprim value ocaml_mem_usage_mem_usage(value unit) {
CAMLparam0();
CAMLlocal1(ret);
struct statfs stats;
uint64_t total_virtual_memory, total_physical_memory,
total_used_physical_memory, total_used_virtual_memory,
process_physical_memory, process_virtual_memory;
process_physical_memory, process_virtual_memory, process_private_memory,
process_swapped_memory;
struct xsw_usage vmem_usage = {0};
size_t size = sizeof(vmem_usage);
struct task_basic_info t_info;
Expand All @@ -74,6 +110,8 @@ CAMLprim value ocaml_mem_usage_mem_usage(value unit) {
mach_port_t mach_port;
mach_msg_type_number_t count;
vm_statistics64_data_t vm_stats;
int pagesize;
unsigned int pages_resident, pages_swapped_out;

caml_release_runtime_system();
if (statfs("/", &stats) != 0) {
Expand Down Expand Up @@ -124,15 +162,23 @@ CAMLprim value ocaml_mem_usage_mem_usage(value unit) {
}
}

pagesize = getpagesize();
private_pages(&pages_resident, &pages_swapped_out);
process_private_memory = pages_resident * pagesize;
process_swapped_memory = pages_swapped_out * pagesize;

caml_acquire_runtime_system();

ret = caml_alloc_tuple(6);
ret = caml_alloc_tuple(8);
;
Store_field(ret, 0, Val_long(total_virtual_memory));
Store_field(ret, 1, Val_long(total_physical_memory));
Store_field(ret, 2, Val_long(total_used_virtual_memory));
Store_field(ret, 3, Val_long(total_used_physical_memory));
Store_field(ret, 4, Val_long(process_virtual_memory));
Store_field(ret, 5, Val_long(process_physical_memory));
Store_field(ret, 6, Val_long(process_private_memory));
Store_field(ret, 7, Val_long(process_swapped_memory));
CAMLreturn(ret);
}
#else
Expand All @@ -148,7 +194,8 @@ CAMLprim value ocaml_mem_usage_mem_usage(value unit) {
struct sysinfo memInfo;
uint64_t total_virtual_memory, total_physical_memory,
total_used_virtual_memory, total_used_physical_memory;
unsigned long long process_virtual_memory, process_physical_memory;
unsigned long long process_virtual_memory, process_physical_memory,
process_private_memory, process_swapped_memory, tmp;
FILE *file;
char buffer[1024] = "";

Expand Down Expand Up @@ -187,15 +234,40 @@ CAMLprim value ocaml_mem_usage_mem_usage(value unit) {
}
fclose(file);
}

process_virtual_memory = 0;
process_swapped_memory = 0;
file = fopen("/proc/self/smaps", "r");
if (file) {
while (fscanf(file, " %1023s", buffer) == 1) {
if (strcmp(buffer, "Private_Dirty:") == 0) {
if (fscanf(file, " %lld", &tmp) != 1)
tmp = 0;
process_virtual_memory += tmp * 1024;
continue;
}

if (strcmp(buffer, "Swap:") == 0) {
if (fscanf(file, " %lld", &tmp) != 1)
tmp = 0;
process_swapped_memory += tmp * 1024;
continue;
}
}
fclose(file);
}

caml_acquire_runtime_system();

ret = caml_alloc_tuple(6);
ret = caml_alloc_tuple(8);
Store_field(ret, 0, Val_long(total_virtual_memory));
Store_field(ret, 1, Val_long(total_physical_memory));
Store_field(ret, 2, Val_long(total_used_virtual_memory));
Store_field(ret, 3, Val_long(total_used_physical_memory));
Store_field(ret, 4, Val_long(process_virtual_memory));
Store_field(ret, 5, Val_long(process_physical_memory));
Store_Field(ret, 6, Val_long(process_private_memory));
Store_Field(ret, 7, Val_long(process_swapped_memory));
CAMLreturn(ret);
}
#endif
4 changes: 3 additions & 1 deletion lib/mem_usage.ml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ type t = {
total_used_physical_memory : int;
process_virtual_memory : int;
process_physical_memory : int;
process_private_memory : int;
process_swapped_memory : int;
}

external info : unit -> t = "ocaml_mem_usage_mem_usage"
Expand Down Expand Up @@ -43,7 +45,7 @@ let prettify_bytes ?(float_printer = Printf.sprintf "%.02f") ?(signed = false)
let exponent =
Float.floor
(if binary then log (float bytes) /. log 1024.
else log10 (float bytes) /. 3.)
else log10 (float bytes) /. 3.)
in
let unit_index =
if List.length units - 1 < int_of_float exponent then
Expand Down
2 changes: 2 additions & 0 deletions lib/mem_usage.mli
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ type t = {
total_used_physical_memory : int;
process_virtual_memory : int;
process_physical_memory : int;
process_private_memory : int;
process_swapped_memory : int;
}

val info : unit -> t
Expand Down
2 changes: 1 addition & 1 deletion mem_usage.opam
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version: "0.1.0"
synopsis: "Cross-platform stats about memory usage"
maintainer: ["The Savonet Team <[email protected]>"]
authors: ["Romain Beauxis <[email protected]>"]
license: "MIT"
license: "GPL-2.0"
homepage: "https://github.com/savonet/ocaml-mem_usage"
bug-reports: "https://github.com/savonet/ocaml-mem_usage/issues"
depends: [
Expand Down
6 changes: 6 additions & 0 deletions test/test.ml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ let () =
total_used_physical_memory;
process_virtual_memory;
process_physical_memory;
process_private_memory;
process_swapped_memory;
} =
Mem_usage.info ()
in
Expand All @@ -23,10 +25,14 @@ Used virtual memory: %s
Used physical memory: %s
Process virtual memory: %s
Process physical memory: %s
Process private memory: %s
Process swapped memory: %s
|}
(Mem_usage.prettify_bytes total_virtual_memory)
(Mem_usage.prettify_bytes total_physical_memory)
(Mem_usage.prettify_bytes total_used_virtual_memory)
(Mem_usage.prettify_bytes total_used_physical_memory)
(Mem_usage.prettify_bytes process_virtual_memory)
(Mem_usage.prettify_bytes process_physical_memory)
(Mem_usage.prettify_bytes process_private_memory)
(Mem_usage.prettify_bytes process_swapped_memory)

0 comments on commit 16e142f

Please sign in to comment.