package memtrace_viewer

  1. Overview
  2. Docs
Interactive memory profiler based on Memtrace

Install

Dune Dependency

Authors

Maintainers

Sources

memtrace_viewer-v0.15.0.tar.gz
sha256=b21d4895f874e48b9f271fb3166ea98c14e7cb1850d621c1e3275f0290d9e338

doc/src/memtrace_viewer.native/user_state.ml.html

Source file user_state.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
open! Core
open! Async
open Memtrace_viewer_common

let percent x = x /. 100.

(* Allocation size (as percentage of total) below which a node is pruned from the trie
   returned to the client. *)
let default_significance_frequency = 0.5 |> percent

(* Upper bound on measurement errors (used in the substring heavy hitters algorithm). *)
let default_tolerance = 0.01 |> percent

(* Number of points in the time series produced for the graph. *)
let graph_size = 450

let time_ns_of_memtrace_timestamp ts =
  Int64.(1000L * (ts |> Memtrace.Trace.Timestamp.to_int64))
  |> Int63.of_int64_exn
  |> Time_ns.of_int63_ns_since_epoch
;;

let info_of_trace_info
      { Memtrace.Trace.Info.sample_rate
      ; word_size
      ; executable_name
      ; host_name
      ; ocaml_runtime_params
      ; pid
      ; start_time
      ; context
      }
  =
  { Data.Info.sample_rate
  ; word_size
  ; executable_name
  ; host_name
  ; ocaml_runtime_params
  ; pid
  ; start_time = start_time |> time_ns_of_memtrace_timestamp
  ; context
  }
;;

module Initial = struct
  type t =
    { trace : Memtrace.Trace.Reader.t
    ; loc_cache : Location.Cache.t
    ; graph : Data.Graph.t
    ; trie : Data.Fragment_trie.t
    ; info : Data.Info.t
    }

  let of_trace trace =
    let loc_cache = Location.Cache.create ~trace () in
    let filtered_trace = Filtered_trace.create ~trace ~loc_cache ~filter:Filter.default in
    let graph = Graph.build ~trace:filtered_trace ~size:graph_size in
    let trie =
      Location_trie.build
        ~trace:filtered_trace
        ~loc_cache
        ~tolerance:default_tolerance
        ~significance_frequency:default_significance_frequency
    in
    let info = info_of_trace_info (Memtrace.Trace.Reader.info trace) in
    { trace; loc_cache; graph; trie; info }
  ;;
end

type t =
  { mutable data : Data.t
  ; mutable filter : Filter.t
  }
[@@deriving fields]

let compute ~initial_state:Initial.{ trace; loc_cache; trie; graph; info } ~filter =
  let total_allocations_unfiltered = Data.Fragment_trie.total_allocations trie in
  let trie, filtered_graph =
    if Filter.is_default filter
    then trie, None
    else (
      let filtered_trace = Filtered_trace.create ~trace ~loc_cache ~filter in
      let trie =
        Location_trie.build
          ~trace:filtered_trace
          ~loc_cache
          ~tolerance:default_tolerance
          ~significance_frequency:default_significance_frequency
      in
      let filtered_graph = Graph.build ~trace:filtered_trace ~size:graph_size in
      trie, Some filtered_graph)
  in
  let hot_paths = Hot_paths.hot_paths trie in
  let hot_call_sites = Hot_call_sites.hot_call_sites trie in
  let info = Some info in
  { Data.graph
  ; filtered_graph
  ; trie
  ; total_allocations_unfiltered
  ; hot_paths
  ; hot_call_sites
  ; info
  }
;;

let create ~initial_state ~filter =
  let data = compute ~initial_state ~filter in
  { data; filter }
;;

let reset initial_state t =
  let filter = Filter.default in
  t.filter <- filter;
  let data = compute ~initial_state ~filter in
  t.filter <- filter;
  t.data <- data
;;

let update initial_state t action =
  match action with
  | Action.Set_filter filter ->
    t.filter <- filter;
    let data = compute ~initial_state ~filter in
    t.data <- data
;;
OCaml

Innovation. Community. Security.