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

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

ただいまの
回答率

88.83%

C#  メモリの合計、使用率の取得、csvファイルへのヘッダーの追加について

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,517

ShinyaKojima

score 18

お世話になっております。

管理用のサーバーでプログラムを起動する際にCPUやメモリにどれくらい負荷がかかっているかを1分おきに取得しcsvとして記録に残したいと考えています。
以前質問でCPU使用率、メモリ使用量については実装できたのですが。今回はメモリ使用率を取得しメモリ全体の何%を占めているのかを調べたいと考えています。

p.WorkingSet64を使ってメモリの使用量を書き出すことは出来たので、
メモリの使用量 / メモリの全体 * 100 = メモリの使用率(%)という風に出せるのではないかと考えたのですが、メモリの全体をどうしたら出せるのかが分かりません。
どなたかご教授お願い致します。

using System;
using System.Threading;
using System.Diagnostics;
using System.IO;
using System.Configuration;

namespace CodeRecipe_Timer_CS
{
    class Program
    {
        static void Main(string[] args)
        {

            using (PerformanceCounter pc = new PerformanceCounter("Processor", "% Processor Time", "_Total", true))
            {
                AutoResetEvent autoEvent = new AutoResetEvent(false);
                TimerCallback tDelegate = new TimerCallback(GetCpuUsage);
                using (Timer oTimer = new Timer(tDelegate, pc, 0, 60000))
                {
                    autoEvent.WaitOne(-1, false);
                  //Thread.Sleep(86400000);
                }
            }
            //Console.WriteLine("Timer を停止しました。終了するには何かキーを押してください。");
            Console.Read();
        }
        static void GetCpuUsage(object state)
        {
            string today = DateTime.Now.ToString("yyyyMMdd");
            string month = DateTime.Now.ToString("yyyyMM");

            PerformanceCounter pc = state as PerformanceCounter;
            DateTime dtNow = DateTime.Now;
            System.Diagnostics.Process p = System.Diagnostics.Process.GetCurrentProcess();
            p.Refresh();

            Microsoft.VisualBasic.Devices.ComputerInfo info =  new Microsoft.VisualBasic.Devices.ComputerInfo();

            if (pc != null)
            {
                //Console.WriteLine(String.Format("現在のCPU使用率は {0:f}% です。" + dtNow.ToString(), pc.NextValue()));
                //Console.WriteLine("物理メモリ使用量: {0}", p.WorkingSet64);
                //Console.WriteLine("仮想メモリ使用量: {0}", p.VirtualMemorySize64);
                File.AppendAllText(ConfigurationManager.AppSettings["key1"] + month + ".csv", String.Format(dtNow.ToString()));
                File.AppendAllText(ConfigurationManager.AppSettings["key1"] + month +".csv", String.Format(",{0:f}% ", pc.NextValue()));

    File.AppendAllText(ConfigurationManager.AppSettings["key1"] + month + ".csv", String.Format(",{0}", (p.WorkingSet64 / メモリ全体 * 100) + "%" + Environment.NewLine));
               // File.AppendAllText(ConfigurationManager.AppSettings["key1"] + today + ".txt", String.Format(" 仮想メモリ使用量: {0}", p.VirtualMemorySize64) + Environment.NewLine);
            }

        }
    }
}

実行結果(メモリ使用率部分は〇〇%に変更、ヘッダー部分は追加したい項目)
201904.csv

日時     CPU使用率 メモリ使用率
2019/4/25 10:03    0.00%    〇〇%
2019/4/25 10:04    19.72%    〇〇%
2019/4/25 10:05    13.48%    〇〇%
2019/4/25 10:06    25.88%    〇〇%
2019/4/25 10:07    22.83%    〇〇%
2019/4/25 10:08    25.26%    〇〇%
2019/4/25 10:09    26.53%    〇〇%
2019/4/25 10:10    18.44%    〇〇%
2019/4/25 10:11    20.40%    〇〇%
2019/4/25 10:12    21.41%    〇〇%
2019/4/25 10:13    22.12%    〇〇%
2019/4/25 10:14    29.45%    〇〇%
2019/4/25 10:15    29.66%    〇〇%
2019/4/25 10:16    21.03%    〇〇%
2019/4/25 10:17    21.06%    〇〇%
2019/4/25 10:18    21.02%    〇〇%
2019/4/25 10:19    17.41%    〇〇%
2019/4/25 10:20    18.85%    〇〇%
2019/4/25 10:21    22.40%    〇〇%
2019/4/25 10:22    17.55%    〇〇%

という風に実現したいと考えています。csvファイルはファイル名を年月にして
1つのcsvの中に1分毎の1行24時間の1か月分でまとめるようにしています。
説明で至らない部分があるかもしれませんが宜しくお願い致します。

やりたいこと
・メモリ全体の取得
・ヘッダーの追加

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • Wind

    2019/04/25 11:12

    System.Diagnostics.Processのプロパティ「PagedSystemMemorySize64」じゃダメなの?
    ヘッダは好きに書けば良いかと。

    キャンセル

  • ShinyaKojima

    2019/04/25 12:45

    System.Diagnostics.Processは
    Using System.Diagnostics.Processってことでしょうか?

    Paged​Memory​Size64
    Gets the amount of paged memory, in bytes, allocated for the associated process.関連付けられたプロセスに割り当てられたページ メモリの量 (バイト単位) を取得します。
    これはメモリの量ってことですね

    まだC#を勉強し始めて日が浅く分からないことだらけだったので・・・

    キャンセル

回答 1

checkベストアンサー

+3

Microsoft.VisualBasic.Devices.ComputerInfo info = new Microsoft.VisualBasic.Devices.ComputerInfo();を持っているようなので、そこから取れると思います。C# メモリサイズ、メモリ使用量などを取得する

//合計物理メモリ
Console.WriteLine("合計物理メモリ:{0}KB", (info.TotalPhysicalMemory/1024));
//利用可能な物理メモリ
Console.WriteLine("利用可能物理メモリ:{0}KB", (info.AvailablePhysicalMemory/1024));
//合計仮想メモリ
Console.WriteLine("合計仮想メモリ:{0}KB", (info.TotalVirtualMemory/1024));
//利用可能な仮想メモリ
Console.WriteLine("利用可能仮想メモリ:{0}KB", (info.AvailableVirtualMemory/1024));

ヘッダについてはデータの出力前にファイルが存在するか確認して、ファイルが無ければヘッダを出力するようにするのがお手軽だと思います。
File.Exists


'ulong' および 'long' のオペランドの演算子 '/' があいまいです

ulongとlongを演算した結果の型は何にすべきか?ulongがulong.MaxValueであり、longが-1の場合、(ulong / long)は-ulong.MaxValueです。これを受け入れられるサイズを持つ整数型はありません。型が決められないのでコンパイラも困ってしまいます。ですので、きちんと型を揃えた状態で計算を実行する必要があります。計算前に型を揃えなければいけない理由は、計算した後、変数に入れるまでの値の扱い(型)をどうするかが決められないからです。(細かい理由は異なると思いますが、そういう風にとらえて問題はないはずです。)

int intValue = 1;
uint uintValue = 2;
var intRes = uintValue / intValue; // この結果はどう頑張ってもlongの範囲内なのでintResはlong型
var uintRes = uintValue * uintValue; // この結果はどう頑張ってもulongの範囲内なのでuintResはulong型

long longValue = -1;
ulong ulongValue = ulong.MaxValue;
var longRes = ulongValue / longValue; // これはどの整数型からもはみ出すのでどうすればいいかわからない!

どの型に揃えるかですが、整数型(ulong, long等)は小数値を切り捨ててしまう為、*100する前に一度0か1になってしまいます。
なので、実数を扱える型にしてください。(doubleあたり?精度を気にするならdecimal?)

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/04/26 11:55 編集

    一番手っ取り早いのがヘッダーに日本語を使わずに
    DATETIME, CPU%, MEM%
    とするとか。

    キャンセル

  • 2019/04/26 11:59

    理由は説明してくださった方がいらっしゃいますので割愛。
    C#は基本UTF-8なのでそのファイルもUTF-8です。
    Excelの
    データ->外部データの取り込み->テキストファイル
    から文字コードにUTF-8を指定すれば読めます。
    SJISで出力したいならFile.AppendAllTextの第三引数にSystem.Text.Encoding.GetEncoding("Shift-Jis")を追加してください。

    キャンセル

  • 2019/04/26 12:48

    なるほど・・・知らないことだらけだったので感動してます。

    ExcelでCSVを開くことが多いので今回は第三引数に追加することにしました。

    結果希望通りの動作になりました。
    レベルの低い質問ばかりで申し訳ありませんでした。

    そして最後まで丁寧な説明ありがとうございました。
    また宜しくお願い致します。

    キャンセル

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

  • ただいまの回答率 88.83%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

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