Skip to content

Instantly share code, notes, and snippets.

View ferd's full-sized avatar
☢️
This place is not a place of honor… no highly esteemed deed is commemorated here

Fred Hebert ferd

☢️
This place is not a place of honor… no highly esteemed deed is commemorated here
View GitHub Profile
-spec gc_count(non_neg_integer(), binary()) -> non_neg_integer().
gc_count(PreviousCounter, Bin) ->
case byte_size(Bin) of
N when N >= 64 -> % refc binary
Count = N + PreviousCounter
case Count >= ?THRESHOLD of
true ->
erlang:garbage_collect(),
0;
false ->
@ferd
ferd / refc_leak_dump.awk
Last active December 19, 2015 22:49
Processing erlang crash dumps to find refc binaries and associated processes
#!/usr/bin/env awk -f
BEGIN {
# crash dump separators
FS=":"
# states
proc=1 # in a proc_heap or proc_stack
binary=2 # after the proc_heap or proc_stack
memory=3 # memory printing area
state=0
min=100
@ferd
ferd / refc_leak.erl
Created July 18, 2013 12:32
Find Erlang processes that may be leaking refc binaries
f(MostLeaky).
MostLeaky = fun(N) ->
lists:sublist(
lists:usort(
fun({K1,V1},{K2,V2}) -> {V1,K1} =< {V2,K2} end,
[try
{_,Pre} = erlang:process_info(Pid, binary),
erlang:garbage_collect(Pid),
{_,Post} = erlang:process_info(Pid, binary),
{Pid, length(Post)-length(Pre)}
@ferd
ferd / percentiles.erl
Created July 16, 2013 13:39
Calculate percentiles in the Erlang shell
f(Percentiles).
Percentiles = fun(Numbers) ->
Percentile = fun(List, Size, Perc) ->
Element = round(Perc * Size),
lists:nth(Element, List)
end,
Len = length(Numbers),
Sorted = lists:sort(Numbers),
[{trunc(Perc*100), Percentile(Sorted, Len, Perc)} ||
Perc <- [0.50, 0.75, 0.90, 0.95, 0.99, 0.999]]
@ferd
ferd / cdumpbin.erl
Created July 12, 2013 19:05
Convert a crash dump Refc binary back to a regular binary. Uses the erl_eval module to evaluate the 16#... hex conversion much faster than naive string handling would do it in this little space.
%% Convert a crashdump binary back into a regular binary
%% Crash dump binary:
%% =binary:CFE75808 % <- reference to refc binary
%% CA:2A31300D0A24350D0A484D5345540D0... % <- actual binary
CDumpBin = fun(Str) ->
[Len,Num] = string:tokens(Str, ":"),
Src= lists:flatten(["<<16#",Num,":(16#",Len,"*8)>>."]),
{ok, Tokens, _}=erl_scan:string(Src),
{ok, [Form]} = erl_parse:parse_exprs(Tokens),
{value, Val, _} = erl_eval:expr(Form, erl_eval:new_bindings()),
@ferd
ferd / gist:5828217
Last active December 18, 2015 18:49
λ self → git clone git@github.com:ferd/vmstats.git
Cloning into 'vmstats'...
Identity added: /Users/ferd/.ssh/id_rsa (/Users/ferd/.ssh/id_rsa)
remote: Counting objects: 83, done.
remote: Compressing objects: 100% (65/65), done.
remote: Total 83 (delta 44), reused 57 (delta 18)
Receiving objects: 100% (83/83), 113.39 KiB, done.
Resolving deltas: 100% (44/44), done.
λ self → cd vmstats
λ vmstats → master → ls
@ferd
ferd / gist:5783802
Created June 14, 2013 17:38
Compare runtime, run queue, and scheduler business
erlang:system_flag(scheduler_wall_time, true),
f(WallTimeDiff),
WallTimeDiff = fun(T1,T2) -> [trunc(100*((Active2-Active1)/(Total2-Total1)))/100 || {{I, Active1, Total1}, {I, Active2, Total2}} <- lists:zip(lists:sort(T1),lists:sort(T2))] end,
f(F), put(stime, erlang:statistics(scheduler_wall_time)),
F = fun(F,N) -> Old=get(stime), New=erlang:statistics(scheduler_wall_time), put(stime,New), io:format("rt:~p\trq:~p\t\tsched:~w~n", [element(2,erlang:statistics(runtime)), erlang:statistics(run_queue), WallTimeDiff(Old,New)]), timer:sleep(N), F(F,N) end.
%% F(F, IntervalInMS).
@ferd
ferd / gist:5708689
Created June 4, 2013 19:19
loop that displays stats for a node
f(Init), f(Loop), f(Stats), f(ShowStats),
Init = fun(Delay) ->
Ref = erlang:start_timer(Delay, self(), '#delay'),
{{input,In},{output,Out}} = erlang:statistics(io),
PrevGC = erlang:statistics(garbage_collection),
{{Delay,Ref}, {In,Out}, PrevGC}
end,
Loop = fun(Self,F,N,{{D,R},{OldIn,OldOut},{OldGCs,OldWords,_}}) ->
receive
{timeout,R,'#delay'} ->
@ferd
ferd / gist:5694838
Last active December 18, 2015 00:09
f(Window).
Window = fun(AttrName, Time,NumProcs) ->
Attrs = fun(Name) ->
[{Pid, {Attr, Curr, Init}}
|| Pid <- processes() -- [self()],
[{_, Attr}, {_, Curr}, {_, Init}] <-
[process_info(Pid, [Name, current_function, initial_call])]]
end,
F = fun() -> Attrs(AttrName) end,
@ferd
ferd / behaviour_parse.erl
Created February 19, 2013 17:09
Parse transform to support -spec and behaviour_info in Erlang
-module(behaviour_parse).
-export([parse_transform/2]).
-define(CUTOFF, "2.15"). % R15B
parse_transform(AST, _Opts) ->
[Vsn] = [X || {kernel,_,X} <- application:which_applications()],
walk_ast(if Vsn >= ?CUTOFF -> spec;
Vsn < ?CUTOFF -> func
end,
AST).