質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.32%

  • C#

    7714questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Visual Studio

    2005questions

    Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

  • Windows 7

    386questions

    Microsoft Windows 7は過去にリリースされたMicrosoft WindowsのOSであり、Windows8の1代前です。2009年の7月にリリースされ販売されました。Windows7の前はWindowsVistaで、その更に3年前にリリースされました。

バイト配列をnewで確保し、処理を抜けて解放することを繰り返しているとWorking Setが上昇する。

受付中

回答 3

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 5,678

fuoh

score 10

処理中、バイト配列をnewで確保し、特に解放処理を行わず、処理を抜けることで解放していると考えています。この処理を定期的に繰り返しているとWorking Setの値が上昇していきます。

ここで質問ですが、Working Setの値が上昇する要因は、何が考えられますでしょうか?

        public byte[] ToByteArray()
        {
            int size;

            // バイト配列に変換
            byte[] temp0 = BitConverter.GetBytes(_DLE);
            byte[] temp1 = BitConverter.GetBytes(_STX);
            byte[] temp2 = BitConverter.GetBytes(_DATALENGTH);
            byte[] temp5 = BitConverter.GetBytes(_BCC);
            byte[] temp6 = BitConverter.GetBytes(_ETX);

            size = GetLength();                ※ 例えば、10と返ってきます

            // 各要素を一つのバイト配列へ格納
            byte[] sendBytes = new byte[size];         ※ ここで、10バイトの領域を確保します
            temp0.CopyTo(sendBytes, 0);
            temp1.CopyTo(sendBytes, 1);
            // ビックエンディアンで格納
            Array.Reverse(temp2);
            temp2.CopyTo(sendBytes, 2);
            _DATA.CopyTo(sendBytes, 4);

            // BCCを計算
            int BCC = 0;
            for (int i = 2; i < (4 + (_DATALENGTH - 1)); i++)
            {
                BCC += sendBytes[i];
            }
            sendBytes[5 + (_DATA.GetLength(0) - 1)] = (byte)(256 - BCC);    // 2の補数をとる
            sendBytes[size - 1] = temp6[0];

            // バイト配列を返す
            return sendBytes;
        }

OS:Windwos 7
言語:C#
開発ツール:Visual Studio 2005
実行環境:.NET Framework 2.0

以下、追記です。
実際に確保するサイズは、65KBを超えません。大きくて600B程です。

現状:
パフォーマンスモニターで、対象アプリのWorking Setを監視しています。
その結果、上昇、下降を繰り返しながら徐々に右肩上がりに上昇しています。

不具合:
対象アプリは、長期実行(24H、365日)するため、メモリが不足することにならないか?

欲しい答え:
サンプルコードのような処理では、問題にならない。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • umyu

    2017/04/10 12:39

    実際のコードでnewで確保しているバイト配列のサイズは85KBを超えてますか?

    キャンセル

  • fuoh

    2017/04/10 13:34

    サイズは、85KBを超えません。大きくても600B程です。

    キャンセル

回答 3

+2

ガベージコレクトされるまで上昇し続けるのは通常の動作ではないでしょうか。

GC.Collect メソッドで強制的にガベージコレクトさせれば想定される動作に近づくかもしれませんが、副作用が想定できません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/10 12:18

    早速のご回答、ありがとうございます。

    説明不足で申し訳ありません。以下追記です。
    Working Setの値ですが、6ヶ月などの長期間実行すると上昇・下降を繰り返し、徐々にですが上昇している状況です。

    キャンセル

  • 2017/04/10 14:55

    どれくらいの期間、間隔ごとに、上限下限を記録し、それがどの程度ずつ上昇しているのでしょうか。

    キャンセル

+2

処理を抜けた時点では開放可能になっただけで、解放されていません。
開放はガベージ・コレクタが行います。
ですから、Working Setの値が上昇は通常は気にする必要はありません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/10 12:14

    早速のご回答、ありがとうございます。

    説明不足で申し訳ありません。以下追記です。
    Working Setの値ですが、6ヶ月などの長期間実行すると上昇・下降を繰り返し、徐々にですが上昇している状況です。

    キャンセル

  • 2017/04/10 12:44

    ご提示のコードの範囲では、メモリリークの要因になりそうなコードは見当たりません。
    >上昇・下降を繰り返し、徐々にですが上昇している
    だから異常ってわけではないです。
    Working Set を監視するツールは何を使っているかなどの情報があれば、もう少し詳しいアドバイスが得られるかもしれません。

    キャンセル

  • 2017/04/10 12:54

    ツールは、パフォーマンスモニタを使用しています。

    キャンセル

  • 2017/04/10 13:48

    聞き方が悪かったかも知れませんが、
    現状:「どんなツールで収集した結果がこんな風になってる」など
    不具合:「それによってこんな不安がある」など
    欲しい答え:「現状が正常であるのか?」など
    をコメント欄ではなく質問に書き足してください。

    キャンセル

  • 2017/04/10 16:53

    サンプルコードのような処理では、問題になりません。
    .netは世代別ガベージコレクションを採用しています。
    若い世代を回収しも古い世代が残ることがあるため、利用メモリが上昇して見えることはあります。しかし必要に応じて古い世代も回収されます。

    キャンセル

+1

こんにちは。

処理を抜けることで解放していると考えています。

ここが違います。
C#はガベージ・コレクション(GC)で使わなくなった(参照されていない)メモリを回収する方式です。
GCは自動的に適宜走るため、実際に回収されるまでにはタイムラグがあります。
ですので、基本的にはワーキングセットの増大はあまり気にしなくて良いです。
.NETアプリケーションとワーキングセットが参考になりそうです。

とはいえ、GCで回収できないメモリ・リークもありますので注意は必要です。
(相互参照や循環参照がある場合や、リスト等へ記録後、使わなくなってもリストの当該要素を解放していないなどなど)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/10 13:41

    早速のご回答、ありがとうございます。

    確認させてください。
    「使わなくなってもリストの当該要素を解放していない」とは、以下の理解でよろしいでしょうか?

     リストにAdd()で要素を追加したが、使用後もそのままとしている。
     Clear()やRemove()等で、要素を削除していない。

    キャンセル

  • 2017/04/10 14:50

    その通りです。

    キャンセル

同じタグがついた質問を見る

  • C#

    7714questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Visual Studio

    2005questions

    Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

  • Windows 7

    386questions

    Microsoft Windows 7は過去にリリースされたMicrosoft WindowsのOSであり、Windows8の1代前です。2009年の7月にリリースされ販売されました。Windows7の前はWindowsVistaで、その更に3年前にリリースされました。

  • トップ
  • C#に関する質問
  • バイト配列をnewで確保し、処理を抜けて解放することを繰り返しているとWorking Setが上昇する。