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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

メモリリーク

メモリリークは、プログラムファイルがメモリの解放に失敗した時に起こります。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

7303閲覧

WindowsXP/7では仮想メモリ量が増えるがWindows10では増えない

sin_250

総合スコア112

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

メモリリーク

メモリリークは、プログラムファイルがメモリの解放に失敗した時に起こります。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

4グッド

0クリップ

投稿2016/04/08 14:53

Windows XPおよびWindows 7では、自作のPythonプログラムを動かすと
タスクマネージャの仮想メモリ欄が(頻繁に増えたり減ったりしつつ)長期的には徐々に増えていくので
何故だ???と頭を悩ませていたのですが、Windows 10で同じプログラムを動かすと、
仮想メモリ欄、その他メモリ関係の数値はピクリとも変わらず一定です。
(Windows 10ではコミットサイズという名前になっていますが)

タスクマネージャで表示される仮想メモリの数字は、実際にプロセスが使用している
数値ではなく、OSが各プロセスに将来使用するかもしれない分なども含めて予約的に割り当てている数値だと理解しています。

当プログラムは長期的に(3か月以上)連続運転したいものなのでメモリリークがあったらまずいなぁと
悩んでいたのですが、結局これはWindows XP, 7のメモリ割り当て管理が下手くそなだけで致命的な障害にはならないだろう、という理解をして問題ないでしょうか。

なおXPでは起動時の仮想メモリは約20MBで、ちょうど12時間で2.6MB増えました。

アドバイスいただけたら幸いです。
なお、私のWindows XP, 7環境では以下のような超簡単なプログラムでも仮想メモリ量は微増していきました。
一体全体、どういう理由なのかわかりません。

Python

1from tkinter import * 2 3class Sample: 4 def __init__(self): 5 self.root = Tk() 6 self.cnt = 0 7 8 self.label = Label(self.root, text = str(self.cnt)) 9 self.label.pack() 10 11 self.root.after(100, self.rewrite) 12 13 def rewrite(self): 14 self.label.configure(text = str(self.cnt)) 15 self.cnt += 1 16 self.root.after(100, self.rewrite) 17#-------------------------------------- Start Main 18if __name__ == "__main__": 19 20 sample = Sample() 21 sample.root.mainloop()
Tak1wa, kei344, ikuwow, argius👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

メモリリークは、不安ですよね、、、

私もWindowsサービスで、1年連続動作させてくれ!みたいな話で、結構がっつりと試験に時間をかけたことがあります。

私がメインでWindowsサービスに関わっていた時には、メモリの確保、破棄(new, deleteとか、malloc,freeとか)の確保サイズや確保時間などによって、しばらくはメモリが増加していく傾向だが(実際に確保している量よりも多く)ある程度で天井になるパターンとか、のこぎり状に、ある程度まで線形的に上がって、ストンと落ちるパターンとか、いくつかのパターンがありましたが、

どちらにしても、総じて、実際に確保している量よりも多めに確保されているのが実際です。

OSのヒープ管理の状態にもよりますが、細かいメモリを、new、deleteする度にメモリを割り当て、解放していたのでは、メモリ上のフラグメントが激しくなり、効率が落ちてしまうため、ある程度無駄を覚悟で連続的にメモリを確保し続けて、解放である程度大きなブロックができたら、OSに返却するという動作をしていると思われます。

また、このメモリの確保、解放の動作については、OSの種類や、使っているベースソフト(Python、JavaScript、C++&MFC、PHP・・・etc)によってそれぞれ実装が違うので、環境によって見た目のメモリの増減がちがってきます。

さて本題です。

メモリリークの判断ということですので、以下を参考に見られるとよいかと思います。

プライベートワーキングセットを見ましょう

タスクマネージャのワーキングセットとかの数値は、さまざまな要素(他にロードしてるモジュールなんか)の関連もあるので)いまひとつ、ぼやっとしてしまいますので、ここは、メモリ(プライベート・・・)とか、
パフォーマンスモニタの、Process > PrivateBytes > 対象のプログラム、で長時間監視をしてみてください。

パフォーマンスモニタならCSVに吐き出せますので、可能であれば加速テスト(通常より多くの処理を走らせる)を行って、みてください。メモリリークしていれが、この値は確実に増加していきます。

この部分で、「自分の」プログラムがある程度リークしていない保証がとれます。

しかし、プライベートワーキングセットは落ち着いていても、プライベートではなく「ワーキングセット」が、もりもり増加をしていく可能性があります。これは、他でロードしているモジュールなど、自分で書いたプログラム領域では無い部分で、リークしている可能性を示しています。このあたりも見ておいた方がよいです。

ただし、先にも書きましたとおり、ある程度増加後、天井を打つようなら、それはリークではない可能性があります、このあたりは実際のプログラムの動作がわからないと、なんともですが。

リークは、メモリだけではありません、リソースリークも見ましょう

こちらは、手っ取り早いのは、タスクマネージャで見られます(パフォーマンスモニタでも見られますので、上記のPrivateByteと一緒にログをとるのが楽です)。
0. ハンドル数
0. スレッド数
0. USERオブジェクト数
0. GDIオブジェクト数

この4つは、確実に見ておいた方がいい数値です。それぞれ徐々に増えていって減らないようであれば危険です。
※この数値は、Windows10では、タスクマネージャでは見られない?のかな?パフォーマンスモニタで確認しないといけないかもしれません。

少々長文になりましたが、パフォーマンスモニタで、すこし長い時間見てみるのがよいかと思います。

投稿2016/04/08 18:31

ItoTomonori

総合スコア1283

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

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

sin_250

2016/04/10 14:36

とても詳細なご回答、まことにありがとうございました。 色々とプログラム構造を試してみたところ、仮想メモリが微増しないような構造を見つけることができました。 また、パフォーマンスモニタでのログ取得はアドバイスに従ってやってみて、それで効果ありのグラフを取ることができました。 ありがとうございました。 PS プログラムを変えてみて効果があったのは、 変更前:メインスレッドから派生した子スレッドでGUIのモジュール(tkinterの関数)を使っていた 変更後:tikinterの関数操作はメインスレッドに限定した。子スレッドのデータをGUIで必要な場合はqueueを使ってデータをやり取り。 何故メインスレッドに限定すると効果があるのかは不明ですが。。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問