Changes between Initial Version and Version 1 of InvestigatingLeaksAndBloat


Ignore:
Timestamp:
Oct 12, 2018 3:28:05 PM (6 years ago)
Author:
Jon Davis
Comment:

Notes from 2018 WebKit Contributors Meeting

Legend:

Unmodified
Added
Removed
Modified
  • InvestigatingLeaksAndBloat

    v1 v1  
     1= Investigating Leaks and Bloat =
     2''by Simon Fraser''
     3
     4- Or… a bunch of half-baked memory tools
     5- Or… don’t be afraid to change code to collect data
     6    - Don’t be scared to do this
     7
     8- Starting problem
     9- “WebContent physical footprint doesn’t go back down significantly after going from nytimes.com to a simple page (about:blank)”
     10- When we say memory use is too high we look at Physical Footprint metric
     11- When measuring memory: Beware of caches
     12- Proper steps
     13    - Load about:blank
     14    - Get physical footprint with `vmmap`
     15    - Load nytimes.com
     16    - Go back to about:blank
     17    - Fire memory warning
     18    - Get physical footprint with `vmmap`
     19- “Something is not going away”
     20    - Leaks?
     21- Tool called “leaks”: `leaks <pid>`
     22- Adding Quick & Easy “State of the world” Data Gathering
     23- Handy too on Mac
     24    - `notifyutil -p`
     25    - Broadcasts notifications to processes, processes can register handlers
     26    - Handles:
     27        - org.WebKit.lowMemory
     28        - com.apple.WebKit.fullGC
     29        - com.apple.WebKit.deleteAllCode
     30        - com.apple.WebKit.Cache.dump
     31        - com.apple.WebKit.showAllDocuments*
     32        - com.apple.WebKit.showMemoryCache*
     33        - com.apple.WebKit.showPageCache*
     34        - * added in last 6 months
     35- `notifyutil -p com.apple.WebKit.showAllDocuments`
     36- Why aren’t they leaks?
     37    - Leaks tool looks for rooted graphs of objects
     38- This is really “Abandonment” or “leaks”
     39- So what objects are hanging around?
     40    - Object Counters
     41- Is this a JS heap issue, or a C++ ref-counting issue?
     42- Which world is the issue happening in?
     43    - Not always easy to tell
     44    - Do the JS* objects go away?
     45    - Did all the doc nodes get destroyed?
     46        - `notifyutil -p com.apple.WebKit.showAllDocuments`
     47        - Look at referencingNodeCount
     48- JS Heap
     49    - GC
     50    - Visist s every object that JS knows about (as JSCell*), starting at GC roots
     51        - JSC::Heap, JSC::SlotVisitor, visistChildren() methods
     52    - Unvisisted objects can be GC
     53    - Doesn’t care about unrooted cycles
     54- GC Heap Inspector
     55    - Heap Snapshots in Web Inspector
     56    - Not quite enough info, no C++ pointer objects
     57- `notifyutil -p com.apple.WebKit.dumpGCHeap`
     58- Checked-in: https://trac.webkit.org/r235271
     59- GC-related Document Leaks
     60    - DFG Scratch buffer
     61    - Exception backtraces
     62    - VM lastException
     63    - JSPerformanceObserverCallback: Strong<Function>
     64        - Strong references indicate GC problems
     65- C++ leaks
     66    - Unbalanced ref()/deref(), retain reference cycles
     67    - `refCount 1` indicates a C++ leak
     68- Ref tracking
     69    - Collate matching ref() and deref() via “tokens”
     70- Ref Token Tracking
     71    - Fix Ref<> and RefPtr<> to store tokens
     72        - All ref() and deref() via  Ref<> and RefPtr<> are tracked
     73- RefTracker class example
     74- Call stack records the ref
     75- StackShot is your friend
     76    - Wrapper for WTFGetBacktrace()
     77    - Washable
     78    - Great for “accumulate all the calls stacks that did this thing”
     79    - Controllable stack depth
     80- TrackedRefCounted<>
     81- Dumping Unmatched Refs
     82    - `RefTracker::dumpRemainingReferences()`
     83- RefTracker is powerful!
     84    - Sometimes dumps the only unmatched `ref()` callstack!
     85    - Easy to patch up manual `ref()`/`deref()` code paths by tracking RefTrackingTokens
     86- webkit.org/b.186269 (reviewz plz)
     87    - Make it possible to track unbalanced ref()/deref()
     88- RefTracker on Node
     89    - Give Node a RefTracker
     90    - Tracks Nodes, Elements, Documents
     91    - Now we can track Document refs
     92    - Hack the “com.apple.WebKit.showAllDocuments” callback to dump ref stacks for live Documents
     93    - You can turn it on and its not a huge perf hit
     94- Making leaks not happen again
     95    - Used GCHeap Inspector
     96    - Fixed a leak
     97- “Finding a regression in EWS is 1000x more efficient than finding it via a perf benchmark regression” — Simon Fraser
     98- webkit.org/b/186214
     99- Isn’t this like the old “world leaks”?
     100    - Sort of is…
     101    - Leaks of world-level objects
     102- Checking for Leaks in Testing
     103    - `./Tools/Scripts/run-webkit-tests --world-leaks`
     104- How it Works
     105    - After each test
     106        - WKBundleGetLiveDocumentURLs()
     107- Implications for run-webkit-tests
     108    - New failure type: “LEAK”
     109    - “LEAK” only relevant if you ran with `--world-leaks`
     110    - Leak checking is post-hoc
     111    - A test can pass, and then become a leak failure
     112- Remaining Work
     113    - Add LEAK expectations for all platforms
     114    - Fix the causes of most common document leaks
     115    - Fix causes of false Leaks
     116    - Turn on by default
     117- C++ Document Leaks
     118    - Web Animations
     119    - Document::removeFocusNavigationNodeofSubtree()
     120    - Content Filtering
     121    - IndexedDB
     122    - SVG text tests
     123    - WebFullScreenManager
     124- C++ Document Lifetime Extenders
     125    - NavigationAction
     126    - Editor/Selection
     127    - ServicesOverlayController
     128    - DragController
     129- To Do
     130    - When WebKitTestRunner detects a leak:
     131        - Dump unmatched refs when tests detect a leak
     132        - Dump a GC heap
     133    - Some auto analysis?
     134- Halp
     135    - webkit.org/b/186214
     136- Now the memory problems are solved, right?
     137    - Not really, still some issues in vmmap
     138    - MALLOC zones
     139    - Dirty size column is interesting, WebKit MALLOC (411 MB)
     140- “Where does all the memory go?”
     141    - webkit.org/b/186422 Create lots of different malloc zones for easier accounting of memory use
     142    - Created custom MALLOC zones for WebKit
     143    - Big ones
     144    - Vector capacity
     145    - HashTable
     146    - webkit.org/b/186698 Make it possible to track all sites that waste container capacity
     147- Container Capacity Tracking
     148    - Give the Vector/HashTable an ID (can’t track by address)
     149    - Record allocation with a StackShot
     150    - On deallocation remove the record
     151    - Dump living capacity:
     152        - Aggregate by StackShot
     153        - Sort by most to least wasteful
     154- Consider not using as many HashTables?
     155    - Maybe use different types of tables?
     156- Memory Reduction
     157    - bmalloc space efficiency
     158        - Maybe as good as system malloc? Problem if using both, using one is fine
     159    - JSC optimizations for space efficiency (even with the JIT)
     160    - WebCore optimizations for space efficiency
     161    - Review Vector and HashTable growth policies
     162        - Resiable hashes (Robin Hood hashing?)
     163    - Vector shrinking
     164    - Convert from HashMaps and HashSets to other data structures
     165    - Adjust caching policies
     166- Better Low Memory Handler
     167    - Don’t dirty more pages than you release
     168        - Organize data structures to release memory without visiting pages
     169    - More use of purgeable memory
     170- WebProcess watermark (big 2.5 GB?)
     171- Space-Efficient Class Layout
     172    - Micro-optimization?
     173    - `dump-class-layout -c Release WebCore FillLayer`
     174    - Look for `<Padding: n bytes>` entries
     175    - Also look at `<UNUSED BITS: n bits>`
     176- std::optional causes these to get big
     177    - There’s been work on different optional types
     178    - Optional with a magic value (doesn’t waste any space)
     179    - Patch for a set of optionals in a bit field
     180- Beware of enums
     181    - For enums, you should specify size
     182- Big Stuff
     183    - Don’t just use all available memory
     184    - Manage cache sizes
     185        - Cache budgets
     186        - JS Heap size
     187- Don’t Cause Leaks
     188    - Be careful with JS bindings code
     189        - JSC::strong<> is almost always wrong
     190    - Be careful with holding refs to Documents, elements
     191        - Avoid cycles
     192        - Avoid extending object lifetimes
     193- Don’t write floaty classes
     194    - Shrink vectors, avoid unused inline capacity on heap-allocated objects
     195    - Do you really need to use HashTable?
     196    - Beware enums and std::optionals
     197- Look for Leaks
     198- Tools for investigating Leaks
     199    - cCache dumping
     200    - GC heap inspector
     201    - Ref token tracking