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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C#

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

Visual Studio

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

Q&A

解決済

1回答

6285閲覧

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

ShinyaKojima

総合スコア18

C#

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

Visual Studio

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

0グッド

0クリップ

投稿2019/04/25 01:57

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

管理用のサーバーでプログラムを起動する際に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か月分でまとめるようにしています。
説明で至らない部分があるかもしれませんが宜しくお願い致します。

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Wind

2019/04/25 02:12

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

2019/04/25 03: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#を勉強し始めて日が浅く分からないことだらけだったので・・・
guest

回答1

0

ベストアンサー

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

C#

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

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


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

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

C#

1int intValue = 1; 2uint uintValue = 2; 3var intRes = uintValue / intValue; // この結果はどう頑張ってもlongの範囲内なのでintResはlong型 4var uintRes = uintValue * uintValue; // この結果はどう頑張ってもulongの範囲内なのでuintResはulong型 5 6long longValue = -1; 7ulong ulongValue = ulong.MaxValue; 8var longRes = ulongValue / longValue; // これはどの整数型からもはみ出すのでどうすればいいかわからない!

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

投稿2019/04/25 02:23

編集2019/04/25 05:29
moredeep

総合スコア1507

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ShinyaKojima

2019/04/25 03:52

//合計物理メモリ Console.WriteLine("合計物理メモリ:{0}KB", (info.TotalPhysicalMemory/1024)); の部分だけ使おうと思ったのですが File.AppendAllText(ConfigurationManager.AppSettings["key1"] + month + ".csv", String.Format(",{0}", ((info.TotalPhysicalMemory / 1024) / (p.WorkingSet64 / 1024) * 100) + "%" + Environment.NewLine)); という風に変更したのですが、 重大度レベル コード 説明 プロジェクト ファイル 行 抑制状態 エラー CS0034 型 'ulong' および 'long' のオペランドの演算子 '/' があいまいです ConsoleApp9 C:\Users\0020H27842\source\repos\ConsoleApp9\ConsoleApp9\Program.cs 46 アクティブ というエラーが発生してしまいました。
ShinyaKojima

2019/04/25 08:24

decimalを知らなかったので調べてみたら正確性ならdecimalが良いみたいですね。今回はメモリ使用率〇〇%辺りで良いのでdoubleで良さそうです。あいまいですというエラーも初めて見て困惑しました。 doubleは種類ですが、 File.AppendAllText(ConfigurationManager.AppSettings["key1"] + month + ".csv", String.Format(",{0}",(info.TotalPhysicalMemory / 1024 / (p.WorkingSet64 / 1024) * 100) + "%" + Environment.NewLine)); だと double tpm = info.TotalPhysicalMemory; //メモリの合計(全体?) double ws = p.WorkingSet64;//物理メモリ使用量 File.AppendAllText(ConfigurationManager.AppSettings["key1"] + month + ".csv", String.Format(",{0}",(ws / tpm * 100) + "%" + Environment.NewLine)); //物理メモリ使用量÷メモリ合計(全体?)=メモリ使用率 という解釈で良いでしょうか? まだまだ文法もろくに覚えれていない初心者なもので・・・(;^_^A
moredeep

2019/04/25 08:43

それで値はちゃんと取れるかと思います。ただ、いちいちdouble変数を定義すると間延びするので、 (double)info.TotalPhysicalMemory / p.WorkingSet64 * 100 でもいいかもしれません。(doubleと整数の演算結果はdouble)
ShinyaKojima

2019/04/26 00:17

なるほど、その方が簡潔にできますね。 最後のFile.Existsについてなんですけど 使い方のイメージとしては指定したファイルがあるかどうかを探してあったら、ヘッダー部分(先頭行)に文字列を追加するという動きだと思います。またファイル名についてはDateTimeで年月.csvになるようにしているので201904.csvのあとは201905.csvになります。この場合DateTimeのmonth(当月)のcsvがあったらヘッダーを追加するという風にしたら前月分のファイルにヘッダーがさらにもう1行追加されるということはないという解釈で間違いないでしょうか? あと、イメージは沸いたのですが、どういう風に書いたら良いのかが分かりません。お手数ですがご教授お願いします。
moredeep

2019/04/26 00:53 編集

ファイルが"無ければ"ヘッダを出力します。 File.AppendAllTextでデータを追加していると思いますが、これはファイルが存在しなければ勝手に作成してくれます。 月が替わった後1回目のデータを書くまではファイルは存在しないため、 if(!File.Exists(ふぁいるぱす)){ File.AppendAllText(ふぁいるぱす, へっだ); } とすれば、1回目のデータが書き込まれる前にヘッダを書き込むことができるはずです。
ShinyaKojima

2019/04/26 01:19

間違えた書き方だったらすみません ふぁいるぱすの部分は絶対パスでDateTimeのmonthを入れて書いてみましたが if(!File.Exists(@" C: \Users\0020H27842\source\repos\ConsoleApp9\ConsoleApp9\bin\Debug" + month + ".csv")) { File.AppendAllText(@"C:\Users\0020H27842\source\repos\ConsoleApp9\ConsoleApp9\bin\Debug" + month + ".csv", "日時", "CPU使用率", "メモリ使用率"); } 重大度レベル コード 説明 プロジェクト ファイル 行 抑制状態 エラー CS1501 引数 4 を指定するメソッド 'AppendAllText' のオーバーロードはありません。 ConsoleApp9 C:\Users\0020H27842\source\repos\ConsoleApp9\ConsoleApp9\Program.cs 43 アクティブ というエラーが出てきました。 あとif(!File.Exists(ふぁいるぱす)の!とはどういう意味なのでしょうか?
moredeep

2019/04/26 02:13

引数 4 を指定するメソッド 'なんちゃら' のオーバーロードはありません。 というのは「引数4つ指定しているけどその関数の引数は4つじゃないよ」って意味です。 File.AppendAllTextの引き数はファイルパスと出力文字列の2つだけです。 へっだの部分には全てのヘッダ文字列を結合したものを指定するか、内容と同じように3回に分けて出力してください。 bool値に付ける感嘆符は真偽値の反転(Not)です。 Console.WriteLine(!false); // True ちょっと、思っていたよりも理解が浅い様子、「C# 入門」等で調べて基礎的なことを調べてみてはいかがでしょうか?
ShinyaKojima

2019/04/26 02:43

ありがとうございます。かなり理解が浅い状態で職場にも詳しい方がいないので、いろんな入門サイトに手を出している感じで、なかなか定着していないみたいです。(;^_^A 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}",(ws / tpm * 100) + "%" + Environment.NewLine)); のように書いていたのに完全に使い方を忘れていました・・・(;^_^A 今回ファイルパスはApp.configでkey1で指定していたので 書き方としては if (!File.Exists(ConfigurationManager.AppSettings["key"] + month + ".csv")) { File.AppendAllText(ConfigurationManager.AppSettings["key"] + month + ".csv", String.Format("日時")); File.AppendAllText(ConfigurationManager.AppSettings["key"] + month + ".csv", String.Format(",CPU使用率")); File.AppendAllText(ConfigurationManager.AppSettings["key"] + month + ".csv", String.Format(",メモリ使用率") + Environment.NewLine); } この場合csvのカンマ区切りでA列B列C列で追加したいのですが A列に書き込まれて しかも文字化けしています。。。 なぜでしょうか
Y.H.

2019/04/26 02:53

> この場合csvのカンマ区切りでA列B列C列で追加したいのですがA列に書き込まれて しかも文字化けしています。。。 もしかしてExcelで開いています? Excelは文字コードSJISでないと文字化けします。「A列に書き込まれて」もcsvの文字コードがSJISでないため列区切の,(カンマ)が見つけられていないためです。
Y.H.

2019/04/26 02:55 編集

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

2019/04/26 02:59

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

2019/04/26 03:48

なるほど・・・知らないことだらけだったので感動してます。 ExcelでCSVを開くことが多いので今回は第三引数に追加することにしました。 結果希望通りの動作になりました。 レベルの低い質問ばかりで申し訳ありませんでした。 そして最後まで丁寧な説明ありがとうございました。 また宜しくお願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問