11 Oracle Machine Learning for Pythonの管理タスク
Pythonプロセスがマシンのリソースを大量に消費していたり、マシンがクラッシュする原因となっていることがわかった場合、Pythonが使用しているリソースに関する情報を取得したり、それに制限を設定できます。
Pythonのシステムおよびプロセス・ユーティリティ・ライブラリpsutil
は、実行中のプロセスやシステム使用率(CPU、メモリー、ディスク、ネットワーク、センサーなど)に関する情報をPythonで取得するためのクロス・プラットフォーム・ライブラリです。これは、システムのモニタリング、プロファイリング、プロセス・リソースの制限、および実行中のプロセスの管理に役立ちます。
psutil.Process.rlimit
関数は、プロセス・リソースの制限を取得または設定します。psutil
では、プロセス・リソースの制限は、名前がpsutil.RLIMIT_
で始まる定数です。それぞれのリソースは、ソフト制限とハード制限のタプルによって制御されます。
たとえば、psutil.RLIMIT_AS
は、プロセスで使用される仮想メモリー(アドレス空間)の最大サイズ(バイト単位)を表します。psutil.RLIMIT_AS
のデフォルト制限が-1 (psutil.RLIM_INFINITY
)に設定されていることがあります。次の例に示すように、psutil.RLIMIT_AS
のリソース制限を低くすることで、Pythonプログラムが大量のデータをメモリーにロードするのを防ぐことができます。
例11-1 psutil.RLIMIT_ASを使用したリソース制御
import psutil
import numpy as np
# Get the current OS process.
p = psutil.Process()
# Get a list of available resources.
[attr for attr in dir(psutil) if attr[:7] == 'RLIMIT_']
# Display the Virtual Memory Size of the current process.
p.memory_info().vms
# Get the process resource limit RLIMIT_AS.
soft, hard = p.rlimit(psutil.RLIMIT_AS)
print('Original resource limits of RLIMIT_AS (soft/hard): {}/{}'.format(soft, hard))
# Check the constant used to represent the limit for an unlimited resource.
psutil.RLIM_INFINITY
# Set resource RLIMIT_AS (soft, hard) limit to (1GB, 2GB).
p.rlimit(psutil.RLIMIT_AS, (pow(1024,3)*1, pow(1024,3)*2))
# Get the current resource limit of RLIMIT_AS.
cur_soft, cur_hard = p.rlimit(psutil.RLIMIT_AS)
print('Current resource limits of RLIMIT_AS (soft/hard): {}/{}'.format(cur_soft, cur_hard))
# Define a list of sizes to be allocated in MB (megabytes).
sz = [5, 10, 20]
# Define a megabyte variable in bytes.
MB = 1024*1024
# Allocate an increasing amount of data.
for val in sz:
stmt = "Allocate %s MB " % val
try:
print("virtual memory: %d MB" % int(p.memory_info().vms/MB))
m = np.arange(val*MB/8, dtype="u8")
print(stmt + " Success.")
except:
print(stmt + " Fail.")
raise
# Delete the allocated variable.
del m
# Raise the soft limit of RLIMIT_AS to 2GB.
p.rlimit(psutil.RLIMIT_AS, (pow(1024,3)*2, pow(1024,3)*2))
# Get the current resource limit of RLIMIT_AS.
cur_soft, cur_hard = p.rlimit(psutil.RLIMIT_AS)
print('Current resource limits of RLIMIT_AS (soft/hard): {}/{}'.format(cur_soft, cur_hard))
# Retry: allocate an increasing amount of data.
for val in sz:
stmt = "Allocate %s MB " % val
try:
print("virtual memory: %d MB" % int(p.memory_info().vms/MB))
m = np.arange(val*MB/8, dtype="u8")
print(stmt + " Success.")
except:
print(stmt + " Fail.")
raise
この例のリスト
>>> import psutil
>>> import numpy as np
>>>
>>> # Get the current OS process.
... p = psutil.Process()
>>>
>>> # Get a list of available resources.
... [attr for attr in dir(psutil) if attr[:7] == 'RLIMIT_']
['RLIMIT_AS', 'RLIMIT_CORE', 'RLIMIT_CPU', 'RLIMIT_DATA',
'RLIMIT_FSIZE', 'RLIMIT_LOCKS', 'RLIMIT_MEMLOCK', 'RLIMIT_MSGQUEUE',
'RLIMIT_NICE', 'RLIMIT_NOFILE', 'RLIMIT_NPROC', 'RLIMIT_RSS',
'RLIMIT_RTPRIO', 'RLIMIT_RTTIME', 'RLIMIT_SIGPENDING', 'RLIMIT_STACK']
>>>
>>> # Display the Virtual Memory Size of the current process.
... p.memory_info().vms
413175808
>>>
>>> # Get the process resource limit RLIMIT_AS.
... soft, hard = p.rlimit(psutil.RLIMIT_AS)
>>> print('Original resource limits of RLIMIT_AS (soft/hard): {}/{}'.format(soft, hard))
Original resource limits of RLIMIT_AS (soft/hard): -1/-1
>>>
>>> # Check the constant used to represent the limit for an unlimited resource.
... psutil.RLIM_INFINITY
-1
>>>
>>> # Set the resource RLIMIT_AS (soft, hard) limit to (1GB, 2GB).
... p.rlimit(psutil.RLIMIT_AS, (pow(1024,3)*1, pow(1024,3)*2))
>>>
>>> # Get the current resource limit of RLIMIT_AS.
... cur_soft, cur_hard = p.rlimit(psutil.RLIMIT_AS)
>>> print('Current resource limits of RLIMIT_AS (soft/hard): {}/{}'.format(cur_soft, cur_hard))
Current resource limits of RLIMIT_AS (soft/hard): 1073741824/2147483648
>>>
>>> # Define a list of sizes to be allocated in MB (megabytes).
... sz = [100, 200, 500, 1000]
>>>
>>> # Define a megabyte variable in bytes.
... MB = 1024*1024
>>>
>>> # Allocate an increasing amount of data.
... for val in sz:
... stmt = "Allocate %s MB " % val
... try:
... print("virtual memory: %d MB" % int(p.memory_info().vms/MB))
... m = np.arange(val*MB/8, dtype="u8")
... print(stmt + " Success.")
... except:
... print(stmt + " Fail.")
... raise
...
virtual memory: 394 MB
Allocate 100 MB Success.
virtual memory: 494 MB
Allocate 200 MB Success.
virtual memory: 594 MB
Allocate 500 MB Fail.
Traceback (most recent call last):
File "<stdin>", line 6, in <module>
MemoryError
>>>
>>> # Delete the allocated variable.
... del m
>>>
>>> # Raise the soft limit of RLIMIT_AS to 2GB.
... p.rlimit(psutil.RLIMIT_AS, (pow(1024,3)*2, pow(1024,3)*2))
>>>
>>> # Get the current resource limit of RLIMIT_AS.
... cur_soft, cur_hard = p.rlimit(psutil.RLIMIT_AS)
>>> print('Current resource limits of RLIMIT_AS (soft/hard): {}/{}'.format(cur_soft, cur_hard))
Current resource limits of RLIMIT_AS (soft/hard): 2147483648/2147483648
>>>
>>> # Retry: allocate an increasing amount of data.
... for val in sz:
... stmt = "Allocate %s MB " % val
... try:
... print("virtual memory: %d MB" % int(p.memory_info().vms/MB))
... m = np.arange(val*MB/8, dtype="u8")
... print(stmt + " Success.")
... except:
... print(stmt + " Fail.")
... raise
...
virtual memory: 458 MB
Allocate 100 MB Success.
virtual memory: 558 MB
Allocate 200 MB Success.
virtual memory: 658 MB
Allocate 500 MB Success.
virtual memory: 958 MB
Allocate 1000 MB Success.