-
Notifications
You must be signed in to change notification settings - Fork 340
Diff heap statistics. #4501
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Diff heap statistics. #4501
Changes from all commits
Commits
Show all changes
171 commits
Select commit
Hold shift + click to select a range
88e3c0d
r
polina-c 40f96b4
-
polina-c 4f35c1b
-
polina-c 87794ef
Merge branch 'master' of github.com:flutter/devtools into size
polina-c 070f797
Update model.dart
polina-c 54a36a1
Update model.dart
polina-c bd4949c
Update model.dart
polina-c 98f58ef
Merge branch 'master' of github.com:flutter/devtools into retained
polina-c 19a7c37
-
polina-c 86700a3
-
polina-c ef2d558
-
polina-c 9991886
-
polina-c fd89707
-
polina-c 4e3f5a0
Update heap_analyzer_test.dart
polina-c 472625b
-
polina-c 1931fea
-
polina-c 0bab199
-
polina-c e51cd2a
-
polina-c 78d65f6
-
polina-c 9e2e970
-
polina-c 93900af
Merge branch 'stager' into size2
polina-c 5afdbfb
Update diff_pane_test.dart
polina-c da0c005
-
polina-c e57318c
-
polina-c f1d9623
Update diff_pane_test.dart
polina-c 4115819
Update diff_pane_test.dart
polina-c ce85cdd
-
polina-c d489a31
-
polina-c 7f7bae1
-
polina-c 3df81f8
-
polina-c e470e4c
Merge branch 'size1' into size2
polina-c 7a85608
-
polina-c 13d2756
Update memory_hover_card.png
polina-c fbc3a6e
-
polina-c 64b20f1
Update memory_diff_empty.png
polina-c 362dd29
-
polina-c 34d6f11
Update model.dart
polina-c a00e502
-
polina-c 07eb2fe
Update mocks.dart
polina-c 41a7553
Update pubspec.yaml
polina-c 380be7f
Update generate_code.sh
polina-c 45dc0e1
Update refresh.sh
polina-c 002d7d5
Update bots.sh
polina-c 6238161
Merge branch 'stager' into size1
polina-c 15fe292
Merge branch 'size1' into size2
polina-c 37230b1
Update diff_pane_test.dart
polina-c 5f1186b
Update common_widgets.dart
polina-c f028530
-
polina-c 91ca15d
-
polina-c 688ba9b
-
polina-c dce7eb7
Merge branch 'master' of github.com:flutter/devtools into size2
polina-c b83af3c
-
polina-c 5966ba6
-
polina-c 97ba965
-
polina-c 5478c00
-
polina-c 25fb537
Update snapshot_view.dart
polina-c e50bf91
-
polina-c 1ee043a
-
polina-c 65dd972
-
polina-c 087043b
-
polina-c 94cbbf8
-
polina-c 1ea913d
-
polina-c dc4e915
Update snapshot_view.dart
polina-c 4fea4a7
-
polina-c 57d8f5f
Update snapshot_control.dart
polina-c 9e7ff13
Merge branch 'master' of github.com:flutter/devtools into size2
polina-c 0f6ce0f
Update diff_pane.dart
polina-c 8671ab4
-
polina-c 5d14a5a
Merge branch 'size2' into diff3
polina-c 95b5878
-
polina-c e6412a5
Update snapshot_control_pane.dart
polina-c 9ab7569
Update model.dart
polina-c e4949de
Merge branch 'master' of github.com:flutter/devtools into size2
polina-c 4c16c17
-
polina-c cd91650
Update diff_pane_controller.dart
polina-c f7fc09e
Update memory_controller.dart
polina-c a6e6743
Merge branch 'size2' into diff3
polina-c 63dc0eb
Update model.dart
polina-c 73d7096
-
polina-c 75d3423
Merge branch 'refactor35' into diff3
polina-c 3d1eda5
-
polina-c fc4dd57
-
polina-c 16237aa
-
polina-c 828970a
Update feature_flags.dart
polina-c ab3ec0a
Update feature_flags.dart
polina-c f357350
Merge branch 'feature_flags' into size2
polina-c e27a0d8
-
polina-c f7c70b3
Update snapshot_view.dart
polina-c 9bb8a87
-
polina-c 7ef3213
-
polina-c 1961b34
-
polina-c afc095e
-
polina-c def70a3
-
polina-c 7fd6469
Merge branch 'master' of github.com:flutter/devtools into size2
polina-c 7ddb3a9
Update offline.dart
polina-c 992008b
Delete offline.dart
polina-c 600b508
Update feature_flags.dart
polina-c 8b4a10f
Merge branch 'size2' into diff3
polina-c 82eec49
-
polina-c 4dbb5b7
Update table_test.dart
polina-c 466c9b2
-
polina-c c3237db
-
polina-c a3f683a
Update common_widgets.dart
polina-c 4a8c2e8
Update memory_diff_three_snapshots.png
polina-c 8740e12
Merge branch 'size2' into diff3
polina-c 6cffd19
Update memory_diff_three_snapshots.png
polina-c b7aca0c
Update memory_diff_three_snapshots.png
polina-c 47d0bc7
Merge branch 'size2' into refactor25
polina-c ad372be
-
polina-c fe6f4e9
-
polina-c cd6d092
-
polina-c 06ea6ba
-
polina-c 4f87f3e
-
polina-c daa54c4
Update snapshot_view.dart
polina-c 03b1888
-
polina-c 6152a03
-
polina-c eadab87
Update snapshot_list.dart
polina-c de6b323
Update snapshot_list.dart
polina-c 9303d1d
Update snapshot_list.dart
polina-c 627fee3
Update snapshot_list.dart
polina-c 203577a
Update memory_controller.dart
polina-c b715b69
Update diff_pane.dart
polina-c 0eb648b
Update snapshot_list.dart
polina-c d932e1d
Update snapshot_list.dart
polina-c ffa4eb1
Update auto_dispose_mixin.dart
polina-c 1d3fbbd
Update snapshot_list.dart
polina-c a7a7819
Update snapshot_list.dart
polina-c ba4d20a
-
polina-c e481ac8
-
polina-c 2961a48
Merge branch 'size2' into refactor25
polina-c 099e4e9
Merge branch 'refactor25' into diff3
polina-c 17b7a4e
-
polina-c 49c4c5c
-
polina-c 75e1017
Merge branch 'master' of github.com:flutter/devtools into refactor25
polina-c d994ca7
-
polina-c befc361
Update model.dart
polina-c 8753246
Merge branch 'refactor25' into diff3
polina-c af05352
-
polina-c c70a2ea
-
polina-c ec57489
-
polina-c 3c26ddf
-
polina-c d7adc73
Merge branch 'refactor25' into diff3
polina-c fbc2334
Update model_test.dart
polina-c 1bc7da9
-
polina-c 66702a5
-
polina-c 8d20b1a
-
polina-c bce22a6
-
polina-c 94a652f
Merge branch 'refactor25' into diff3
polina-c ff510c0
-
polina-c f735e65
-
polina-c f598998
Update snapshot_view.dart
polina-c 94f4b04
-
polina-c 2b75990
Merge branch 'refactor25' into diff3
polina-c 3647fdf
Merge branch 'diff3' into details4
polina-c c6a81a2
Update stats_table.dart
polina-c 6b29f53
Merge branch 'master' of github.com:flutter/devtools into diff3
polina-c 5163358
Merge branch 'diff3' into details4
polina-c 86393ef
to-controller1
polina-c 9ee2f4b
-
polina-c e64236a
Update table_test.dart
polina-c 48dd684
-
polina-c 60d024d
-
polina-c ee60ec8
Merge branch 'master' of github.com:flutter/devtools into details4
polina-c 1b1b019
Update diff_pane_controller.dart
polina-c 7f54c00
-
polina-c a704f48
Update model.dart
polina-c 3ffb431
-
polina-c 9739f90
-
polina-c 63cf573
-
polina-c 47e569f
-
polina-c 7a1f04b
Update snapshot_control_pane.dart
polina-c File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
102 changes: 102 additions & 0 deletions
102
packages/devtools_app/lib/src/screens/memory/panes/diff/controller/heap_diff.dart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
// Copyright 2022 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
import 'package:flutter/foundation.dart'; | ||
|
||
import '../../../shared/heap/heap.dart'; | ||
import '../../../shared/heap/model.dart'; | ||
|
||
/// Stores already calculated comparisons for heap couples. | ||
class HeapDiffStore { | ||
final _store = <_HeapCouple, HeapComparison>{}; | ||
|
||
HeapComparison compare(AdaptedHeap heap1, AdaptedHeap heap2) { | ||
final couple = _HeapCouple(heap1, heap2); | ||
return _store.putIfAbsent(couple, () => HeapComparison(couple)); | ||
} | ||
} | ||
|
||
@immutable | ||
class _HeapCouple { | ||
_HeapCouple(AdaptedHeap heap1, AdaptedHeap heap2) { | ||
older = _older(heap1, heap2); | ||
younger = older == heap1 ? heap2 : heap1; | ||
} | ||
|
||
late final AdaptedHeap older; | ||
late final AdaptedHeap younger; | ||
|
||
/// Finds most deterministic way to declare earliest heap. | ||
/// | ||
/// If earliest heap cannot be identified, returns first argument. | ||
static AdaptedHeap _older(AdaptedHeap heap1, AdaptedHeap heap2) { | ||
assert(heap1.data != heap2.data); | ||
if (heap1.data.created.isBefore(heap2.data.created)) return heap1; | ||
if (heap2.data.created.isBefore(heap1.data.created)) return heap2; | ||
if (identityHashCode(heap1) < identityHashCode(heap2)) return heap1; | ||
if (identityHashCode(heap2) < identityHashCode(heap1)) return heap2; | ||
if (identityHashCode(heap1.data) < identityHashCode(heap2.data)) | ||
return heap1; | ||
if (identityHashCode(heap2.data) < identityHashCode(heap1.data)) | ||
return heap2; | ||
return heap1; | ||
} | ||
|
||
@override | ||
bool operator ==(Object other) { | ||
if (other.runtimeType != runtimeType) { | ||
return false; | ||
} | ||
return other is _HeapCouple && | ||
other.older == older && | ||
other.younger == younger; | ||
} | ||
|
||
@override | ||
int get hashCode => Object.hash(older, younger); | ||
} | ||
|
||
class HeapComparison { | ||
HeapComparison(this.heapCouple); | ||
|
||
late final HeapStatistics stats = _stats(); | ||
|
||
final _HeapCouple heapCouple; | ||
|
||
HeapStatistics _stats() { | ||
final result = <String, HeapStatsRecord>{}; | ||
|
||
final older = heapCouple.older.stats.recordsByClass; | ||
final younger = heapCouple.younger.stats.recordsByClass; | ||
|
||
final unionOfKeys = older.keys.toSet().union(younger.keys.toSet()); | ||
|
||
for (var key in unionOfKeys) { | ||
final olderRecord = older[key]; | ||
final youngerRecord = younger[key]; | ||
|
||
if (olderRecord != null && youngerRecord != null) { | ||
final diff = _diffStatsRecords(olderRecord, youngerRecord); | ||
if (!diff.isZero) result[key] = diff; | ||
} else if (youngerRecord != null) { | ||
result[key] = youngerRecord; | ||
} else { | ||
result[key] = olderRecord!.negative(); | ||
} | ||
} | ||
|
||
return HeapStatistics(result); | ||
} | ||
|
||
static HeapStatsRecord _diffStatsRecords( | ||
HeapStatsRecord older, | ||
HeapStatsRecord younger, | ||
) { | ||
assert(older.heapClass.fullName == younger.heapClass.fullName); | ||
return HeapStatsRecord(older.heapClass) | ||
..instanceCount = younger.instanceCount - older.instanceCount | ||
..shallowSize = younger.shallowSize - older.shallowSize | ||
..retainedSize = younger.retainedSize - older.retainedSize; | ||
} | ||
} |
97 changes: 97 additions & 0 deletions
97
packages/devtools_app/lib/src/screens/memory/panes/diff/controller/item_controller.dart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// Copyright 2022 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
import 'package:flutter/foundation.dart'; | ||
|
||
import '../../../../../primitives/auto_dispose.dart'; | ||
import '../../../../../primitives/utils.dart'; | ||
import '../../../shared/heap/heap.dart'; | ||
import '../../../shared/heap/model.dart'; | ||
import 'heap_diff.dart'; | ||
|
||
abstract class DiffListItem extends DisposableController { | ||
/// Number, that if shown in name, should be unique in the list. | ||
/// | ||
/// If the number is not expected to be shown in UI, it should be 0. | ||
int get displayNumber; | ||
|
||
ValueListenable<bool> get isProcessing => _isProcessing; | ||
final _isProcessing = ValueNotifier<bool>(false); | ||
|
||
/// If true, the item contains data, that can be compared and analyzed. | ||
bool get hasData; | ||
} | ||
|
||
class InformationListItem extends DiffListItem { | ||
@override | ||
int get displayNumber => 0; | ||
|
||
@override | ||
bool get hasData => false; | ||
} | ||
|
||
class SnapshotListItem extends DiffListItem with AutoDisposeControllerMixin { | ||
SnapshotListItem( | ||
Future<AdaptedHeapData?> receiver, | ||
this.displayNumber, | ||
this._isolateName, | ||
this.diffStore, | ||
this.selectedClassName, | ||
) { | ||
_isProcessing.value = true; | ||
receiver.whenComplete(() async { | ||
final data = await receiver; | ||
if (data != null) { | ||
heap = AdaptedHeap(data); | ||
updateSelectedRecord(); | ||
addAutoDisposeListener(selectedClassName, () => updateSelectedRecord()); | ||
} | ||
_isProcessing.value = false; | ||
}); | ||
} | ||
|
||
final String _isolateName; | ||
|
||
final HeapDiffStore diffStore; | ||
|
||
AdaptedHeap? heap; | ||
|
||
@override | ||
final int displayNumber; | ||
|
||
String get name => '$_isolateName-$displayNumber'; | ||
|
||
var sorting = ColumnSorting(); | ||
|
||
ValueListenable<SnapshotListItem?> get diffWith => _diffWith; | ||
final _diffWith = ValueNotifier<SnapshotListItem?>(null); | ||
void setDiffWith(SnapshotListItem? value) { | ||
_diffWith.value = value; | ||
updateSelectedRecord(); | ||
} | ||
|
||
final ValueListenable<String?> selectedClassName; | ||
|
||
ValueListenable<HeapStatsRecord?> get selectedRecord => _selectedRecord; | ||
final _selectedRecord = ValueNotifier<HeapStatsRecord?>(null); | ||
|
||
@override | ||
bool get hasData => heap != null; | ||
|
||
HeapStatistics get statsToShow { | ||
final theHeap = heap!; | ||
final itemToDiffWith = diffWith.value; | ||
if (itemToDiffWith == null) return theHeap.stats; | ||
return diffStore.compare(theHeap, itemToDiffWith.heap!).stats; | ||
} | ||
|
||
void updateSelectedRecord() => _selectedRecord.value = | ||
statsToShow.recordsByClass[selectedClassName.value]; | ||
} | ||
|
||
class ColumnSorting { | ||
bool initialized = false; | ||
SortDirection direction = SortDirection.ascending; | ||
int columnIndex = 0; | ||
} |
58 changes: 0 additions & 58 deletions
58
packages/devtools_app/lib/src/screens/memory/panes/diff/controller/model.dart
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
packages/devtools_app/lib/src/screens/memory/panes/diff/widgets/class_details.dart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// Copyright 2022 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
import 'package:flutter/widgets.dart'; | ||
|
||
import '../../../shared/heap/model.dart'; | ||
|
||
class HeapClassDetails extends StatelessWidget { | ||
const HeapClassDetails({Key? key, required this.heapClass}) : super(key: key); | ||
|
||
final HeapClass? heapClass; | ||
polina-c marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
@override | ||
Widget build(BuildContext context) { | ||
final theClass = heapClass; | ||
if (theClass == null) { | ||
return const Center( | ||
child: Text('Select class to see details here.'), | ||
); | ||
} | ||
return Center(child: Text('Details for ${theClass.fullName} will be here')); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be captured by the
other is _HeapCouple
checkThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copied it from https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#common-boilerplates-for-operator--and-hashcode.
I would stay with the standard.
Maybe
is
is more expensive and we want to exit early?