質問するログイン新規登録

質問編集履歴

3

「詳しくは、最下部の「追記」項目をお読みください。「該当のソースコード」項目は読み飛ばしていただいてもかまいません。」を文章内に追記

2018/03/29 17:05

投稿

myora
myora

スコア7

title CHANGED
File without changes
body CHANGED
@@ -7,6 +7,8 @@
7
7
  メモリリークと思われる現象が発生しており、折れ線グラフを更新するたびに、使用メモリが増えていきます。また、描画までにかかる処理時間もだんだんと遅くなっていきます(15回グラフ更新すると、1,2秒遅くなりました)。
8
8
  メモリリークしていることも謎ですが、描画時間が遅くなることのほうが疑問に感じています。
9
9
 
10
+ 詳しくは、最下部の「追記」項目をお読みください。「該当のソースコード」項目は読み飛ばしていただいてもかまいません。
11
+
10
12
  ### 該当のソースコード
11
13
  こちらがソースコードです。このアプリは、ボタンを押下すると、500点からなる折れ線グラフを描画・更新します。描画する500点は起動時に乱数によって決定します。
12
14
 

2

Itemクラスの修正

2018/03/29 17:05

投稿

myora
myora

スコア7

title CHANGED
File without changes
body CHANGED
@@ -136,13 +136,41 @@
136
136
 
137
137
  namespace ChartTest
138
138
  {
139
- public class Item : INotifyPropertyChanged
139
+ public class Item : INotifyPropertyChanged
140
140
  {
141
- public double Key { get; set; }
142
- public double Value { get; set; }
143
-
144
141
  public event PropertyChangedEventHandler PropertyChanged;
142
+ private void RaisePropertyChanged([CallerMemberName]string propertyName = null)
143
+ {
144
+ if (PropertyChanged != null)
145
+ PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
146
+ }
145
147
 
148
+ private double x;
149
+ private double y;
150
+
151
+ public double Key {
152
+ get { return x; }
153
+ set {
154
+ if (value != x)
155
+ {
156
+ x = value;
157
+ RaisePropertyChanged();
158
+ }
159
+ }
160
+ }
161
+ public double Value
162
+ {
163
+ get { return y; }
164
+ set
165
+ {
166
+ if (value != y)
167
+ {
168
+ y = value;
169
+ RaisePropertyChanged();
170
+ }
171
+ }
172
+ }
173
+
146
174
  }
147
175
 
148
176
  public sealed partial class MainPage : Page

1

メモリリークする、処理が遅くなる、についての詳細な測定結果について「追記」に記載しました

2018/03/29 15:51

投稿

myora
myora

スコア7

title CHANGED
File without changes
body CHANGED
@@ -95,4 +95,133 @@
95
95
 
96
96
  開発環境は、Visual Studio 2017 Communityです。
97
97
 
98
- Debug版での実行に基づき、メモリや処理速度を判断しています。
98
+ Debug版での実行に基づき、メモリや処理速度を判断しています。
99
+
100
+
101
+ ### 追記
102
+ メモリリークする、処理が遅くなる、についての詳細な部分について記載します。
103
+
104
+ まず、検証するソースコードですが、今後の実用性の観点から以下のようなアプリに変更しました。
105
+ アプリ概要: 「グラフ生成」と「グラフクリア」の二つのボタンが配置されている。「グラフ生成」ボタンを押下すると、10点分の折れ線グラフが30個描画される。次に、「グラフクリア」ボタンを押下すると、描画されているグラフを消す。
106
+
107
+ 「グラフ生成」ボタンを押下後のイメージ
108
+ ![グラフの描画時](febe0bf33c3ee01171f317c0b7b1e362.png)
109
+
110
+ ソースコード
111
+ ```Xaml
112
+ <Page
113
+ x:Class="ChartTest.MainPage"
114
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
115
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
116
+ xmlns:local="using:ChartTest"
117
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
118
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
119
+ xmlns:Charting="using:WinRTXamlToolkit.Controls.DataVisualization.Charting"
120
+ mc:Ignorable="d">
121
+
122
+ <Grid x:Name="Grid" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
123
+
124
+ <Charting:Chart Name="LineChart01" Margin="33,154,49,34">
125
+ </Charting:Chart>
126
+ <Button Content="グラフ生成" HorizontalAlignment="Left" Height="114" Margin="108,21,0,0" VerticalAlignment="Top" Width="496" Click="Button_Create_Click"/>
127
+ <Button Content="グラフクリア" HorizontalAlignment="Left" Height="114" Margin="749,21,0,0" VerticalAlignment="Top" Width="496" Click="Button_Clear_Click"/>
128
+
129
+ </Grid>
130
+ </Page>
131
+ ```
132
+
133
+ ```C#
134
+ using WinRTXamlToolkit.Controls.DataVisualization.Charting;
135
+
136
+
137
+ namespace ChartTest
138
+ {
139
+ public class Item : INotifyPropertyChanged
140
+ {
141
+ public double Key { get; set; }
142
+ public double Value { get; set; }
143
+
144
+ public event PropertyChangedEventHandler PropertyChanged;
145
+
146
+ }
147
+
148
+ public sealed partial class MainPage : Page
149
+ {
150
+
151
+ List<ObservableCollection<Item>> itemsList;
152
+
153
+ public MainPage()
154
+ {
155
+ this.InitializeComponent();
156
+
157
+ // 描画するグラフのList生成
158
+ itemsList = new List<ObservableCollection<Item>>();
159
+ Random rnd = new System.Random();
160
+        // 30個のグラフを表示
161
+ for (int j = 0; j < 30; j++)
162
+ {
163
+ // それぞれのグラフに10点の値を入れる。
164
+ ObservableCollection<Item> items = new ObservableCollection<Item>();
165
+ for (int i = 0; i < 10; i++)
166
+ {
167
+ items.Add(new Item { Key = i, Value = rnd.Next(0, 100) });
168
+ }
169
+ itemsList.Add(items);
170
+ }
171
+ }
172
+
173
+ // ボタンクリックでグラフの生成
174
+ private void Button_Create_Click(object sender, RoutedEventArgs e)
175
+ {
176
+ int i = 0;
177
+ // グラフの数だけ描画する
178
+ foreach (var items in itemsList)
179
+ {
180
+
181
+ // LineSeries 生成
182
+ LineSeries lineSeries = new LineSeries()
183
+ {
184
+ ItemsSource = items,
185
+ IndependentValuePath = "Key",
186
+ DependentValuePath = "Value",
187
+ Title = i
188
+ };
189
+
190
+ // SeriesにAdd
191
+ this.LineChart01.Series.Add(lineSeries);
192
+
193
+ i++;
194
+ }
195
+ }
196
+
197
+ // ボタンクリックでグラフのクリア
198
+ private void Button_Clear_Click(object sender, RoutedEventArgs e)
199
+ {
200
+ // SeriesのCollectionを初期化
201
+ this.LineChart01.Series.Clear();
202
+ }
203
+ }
204
+ }
205
+ ```
206
+
207
+ 次に、グラフ描画時間とメモリの測定です。
208
+ [1]. 本アプリをDebugモードで起動します。
209
+ [2]. 「グラフ生成」ボタン押下 → 「グラフクリア」ボタン押下 → 「グラフ生成」ボタン押下 → ・・・
210
+  と繰り返します。
211
+ [3]. この時の、各ボタンを押下してから処理が完了するまでの時間を、Debugモードの診断ツールのプロセスメモリグラフとCPUグラフの処理時間から読み取ります。
212
+
213
+ 測定結果が以下です。(1枚目がシステム起動時、2枚目が上記の[2].を5分間繰り返したときの画像です)
214
+ 赤丸の部分が、「グラフ生成」ボタンを押下してから、グラフが描画されるまでの時間で、
215
+ 青丸の部分が、「グラフクリア」ボタンを押下してから、グラフが消えるまでの時間です。
216
+
217
+ システム起動時
218
+ ![システム起動時](8b321d0ac570583cf22a6a3a885805b0.jpeg)
219
+ 5分経過時
220
+ ![5分経過時](aeba00b91768f40dd2994342a146e0bc.jpeg)
221
+
222
+ 上記のグラフから、以下のことが言えると考えました。
223
+ ・メモリは起動時には急激に増加し、それ以降は、徐々に増加していく。
224
+ ・処理時間は、グラフ描画時間はほとんど変わらないが、グラフクリアをする時間が5分経過時には、2倍近く遅くなっている。
225
+
226
+ とくに、処理時間が遅くなることが困っています。
227
+ アドバイス等ありましたらよろしくお願いします。