From a6cc988f5e498edf258d4af3cd7f7af1813a2355 Mon Sep 17 00:00:00 2001 From: Jim Myhrberg Date: Sun, 8 Jul 2018 18:38:35 +0100 Subject: [PATCH] Ensure all exported functions and types have descriptive comments --- leak/finder.go | 12 ++++++++++++ obj/dump.go | 6 ++++++ obj/entry.go | 3 +++ obj/object.go | 5 +++++ 4 files changed, 26 insertions(+) diff --git a/leak/finder.go b/leak/finder.go index 2fa01b6..c0b7f64 100644 --- a/leak/finder.go +++ b/leak/finder.go @@ -7,12 +7,16 @@ import ( "github.com/jimeh/rbheap/obj" ) +// NewFinder returns a new *Finder instance, populated with the three given file +// paths. func NewFinder(filePath1, filePath2, filePath3 string) *Finder { return &Finder{ FilePaths: [3]string{filePath1, filePath2, filePath3}, } } +// Finder helps with finding a memory leak across three different memory dumps +// from a Ruby process. type Finder struct { FilePaths [3]string Dumps [3]*obj.Dump @@ -20,6 +24,7 @@ type Finder struct { Verbose bool } +// Process will will load and process each of the dump files. func (s *Finder) Process() error { for i, filePath := range s.FilePaths { start := time.Now() @@ -43,16 +48,23 @@ func (s *Finder) Process() error { return nil } +// PrintLeakedAddresses prints the memory addresses in hex (0x...) format for +// all objects which are likely to be leaked memory. func (s *Finder) PrintLeakedAddresses() { s.log("\nLeaked Addresses:") s.Dumps[1].PrintEntryAddress(s.FindLeaks()) } +// PrintLeakedObjects prints the full JSON blobs for all objects which are +// likely to be memory leaks. func (s *Finder) PrintLeakedObjects() error { s.log("\nLeaked Objects:") return s.Dumps[1].PrintEntryJSON(s.FindLeaks()) } +// FindLeaks finds potential memory leaks by removing all objects in heap dump +// #1 from heap dump #2, and then also removing all entries from heap dump #2 +// which are not present in heap dump #3. func (s *Finder) FindLeaks() []*string { if s.Leaks != nil { return s.Leaks diff --git a/obj/dump.go b/obj/dump.go index 1810b24..8e863e2 100644 --- a/obj/dump.go +++ b/obj/dump.go @@ -8,6 +8,7 @@ import ( "sort" ) +// NewDump returns a *Dump instance populated with the specified file path. func NewDump(filePath string) *Dump { return &Dump{FilePath: filePath} } @@ -54,6 +55,8 @@ func (s *Dump) Process() error { return nil } +// PrintEntryAddress prints the memory addresses in hex (0x...) format of the +// entries for the list of given indexes. func (s *Dump) PrintEntryAddress(indexes []*string) { for _, index := range indexes { if entry, ok := s.Entries[*index]; ok { @@ -62,6 +65,9 @@ func (s *Dump) PrintEntryAddress(indexes []*string) { } } +// PrintEntryJSON prints the full JSON blob from the input file for the entries +// with the given indexes. It does this by using the Offset value of the entries +// to avoid having to load up the whole dump file in memory. func (s *Dump) PrintEntryJSON(indexes []*string) error { file, err := os.Open(s.FilePath) defer file.Close() diff --git a/obj/entry.go b/obj/entry.go index aba3886..60179d9 100644 --- a/obj/entry.go +++ b/obj/entry.go @@ -1,5 +1,7 @@ package obj +// NewEntry returns a new *Entry instance initialized with a *Object of the +// given input JSON data. func NewEntry(inputJSON []byte) (*Entry, error) { obj, err := NewObject(inputJSON) if err != nil { @@ -19,6 +21,7 @@ type Entry struct { Index string } +// Address returns the Address property of the entry's Object. func (s *Entry) Address() string { return s.Object.Address } diff --git a/obj/object.go b/obj/object.go index 675c04c..ae4aa3e 100644 --- a/obj/object.go +++ b/obj/object.go @@ -4,6 +4,8 @@ import "encoding/json" //go:generate easyjson -all object.go +// NewObject returns a new *Object instance with it's attributes populated from +// the given input JSON data. func NewObject(inputJSON []byte) (*Object, error) { var obj Object err := json.Unmarshal(inputJSON, &obj) @@ -11,11 +13,14 @@ func NewObject(inputJSON []byte) (*Object, error) { return &obj, err } +// Object is a minimal representation of a Ruby heap object as exported from +// Ruby via `ObjectSpace.dump_all`. type Object struct { Address string `json:"address"` Type string `json:"type"` } +// Index returns a unique index for the given Object. func (s *Object) Index() string { return s.Address + ":" + s.Type }