2015-09-20 27 views
5

Python 3 liczby całkowite mają unlimited precision. W praktyce jest to ograniczone przez pamięć komputera.Python Infinite Integers

Rozważmy kod followng:

i = 12345 
while True: 
    i = i * 123 

To oczywiście niepowodzeniem. Ale jaki będzie tego wynik? Cała pamięć RAM (i plik strony) jest wypełniona tą jedną liczbą całkowitą (z wyjątkiem miejsca zajmowanego przez inne procesy)?

Czy istnieje zabezpieczenie, aby złapać to, zanim dojdzie tak daleko?

+1

Uderzysz w MemoryError –

+0

. Tak więc większość pamięci RAM i pliku stronicowania zostanie nadpisana? – mcu

+0

Zależy od tego, na co pozwala system operacyjny, i czy "i" rozpoczęło się od zera, czy nie. –

Odpowiedz

1

Można sprawdzić, co się dzieje, nie ryzykując wypełnienia całej dostępnej pamięci. Mogłabyś set the memory limit explicitly:

#!/usr/bin/env python 
import contextlib 
import resource 

@contextlib.contextmanager 
def limit(limit, type=resource.RLIMIT_AS): 
    soft_limit, hard_limit = resource.getrlimit(type) 
    resource.setrlimit(type, (limit, hard_limit)) # set soft limit 
    try: 
     yield 
    finally: 
     resource.setrlimit(type, (soft_limit, hard_limit)) # restore 

with limit(100 * (1 << 20)): # 100MiB 
    # do the thing that might try to consume all memory 
    i = 1 
    while True: 
     i <<= 1 

Kod ten zużywa 100% CPU (na jednym rdzeniu) i spożywane pamięć rośnie bardzo powoli.

Zasadniczo powinieneś dostać MemoryError w pewnym momencie, czy stanie się to zanim twój komputer zamieni się w pył jest niejasny. CPython uses a continuous block of memory to store the digits i dlatego może pojawić się błąd, nawet jeśli jest dostępna pamięć RAM, ale jest pofragmentowana.

Twój konkretny kod nie powinien go wyzwalać, ale ogólnie możesz również uzyskać OverflowError if you try to construct an integer larger than sys.maxsize bytes.

+0

Tak więc, nie będzie żadnych wycieków do pliku stronicowania, ponieważ nie będzie on ciągły. – mcu

+0

@ coding4fun: python nie dba o to skąd pochodzi pamięć. To, czy system operacyjny używa pliku stronicowania, czy nie, jest całkowicie przezroczyste dla Pythona. Wygląda na to, że algorytm jest zbyt wolny, aby i tak wypełnić pamięć. – jfs