get_memory_info() -> get_memory_info(os:type()).
get_memory_info({unix, linux}) ->
File = read_proc_file("/proc/meminfo"),
Lines = string:tokens(File, "\n"),
Dict = dict:from_list(lists:map(fun parse_line_linux/1, Lines)),
MemTotal = dict:fetch('MemTotal', Dict),
MemFree = dict:fetch('MemFree', Dict),
SwapTotal = dict:fetch('SwapTotal', Dict),
SwapFree = dict:fetch('SwapFree', Dict),
Inactive = dict:fetch('Inactive', Dict),
PhysicalMemorySize = MemTotal,
VirtualMemorySize = MemTotal + SwapTotal,
AvailablePhysicalMemorySize = MemFree + Inactive,
AvailableVirtualMemorySize = MemFree + Inactive + SwapFree,
{ok, {PhysicalMemorySize, VirtualMemorySize, AvailablePhysicalMemorySize, AvailableVirtualMemorySize}}.
%% A line looks like "MemTotal: 1683444 kB"
parse_line_linux(Line) ->
[Name, RHS | _Rest] = string:tokens(Line, ":"),
[Value | UnitsRest] = string:tokens(RHS, " "),
Value1 = case UnitsRest of
[] -> list_to_integer(Value); %% no units
["kB"] -> list_to_integer(Value) * 1024
end,
{list_to_atom(Name), Value1}.
%% file:read_file does not work on files in /proc as it seems to get
%% the size of the file first and then read that many bytes. But files
%% in /proc always have length 0, we just have to read until we get
%% eof.
read_proc_file(File) ->
{ok, IoDevice} = file:open(File, [read, raw]),
Res = read_proc_file(IoDevice, []),
file:close(IoDevice),
lists:flatten(lists:reverse(Res)).
-define(BUFFER_SIZE, 1024).
read_proc_file(IoDevice, Acc) ->
case file:read(IoDevice, ?BUFFER_SIZE) of
{ok, Res} -> read_proc_file(IoDevice, [Res | Acc]);
eof -> Acc
end.
附带erlang自带的内存监控模块:(需要先开启sasl下的os_mon模块)
application:start(sasl),application:start(os_mon).
L = memsup:get_system_memory_data(),
Total = proplists:get_value(total_memory, L),
Freed = proplists:get_value(free_memory, L),
Cached = proplists:get_value(cached_memory, L),
{ok, (Total - Freed - Cached)*100 div Total}.