Python memory error stack overflow

[Found solution by Kailey Case] Sys.setrecursionlimit(limit) Set the maximum depth of the Python interpreter stack to limit. This limit prevents infinite recursion from causin

Answer by Kailey Case

sys.setrecursionlimit(limit) Set the maximum depth of the Python
interpreter stack to limit. This limit prevents infinite recursion
from causing an overflow of the C stack and crashing Python.,If the new limit is too low at the current recursion depth, a
RecursionError exception is raised.,You are getting the stackoverflow because you set the recursion limit too high. You can’t set it as high as you like,Changed in version 3.5.1: A RecursionError exception is now raised if
the new limit is too low at the current recursion depth.

sys.setrecursionlimit(limit) Set the maximum depth of the Python
interpreter stack to limit. This limit prevents infinite recursion
from causing an overflow of the C stack and crashing Python.

sys.setrecursionlimit(limit)

Answer by Marleigh Villa

Exception

MemoryError

,BaseException

Exception

MemoryError

,We’ll start by using the Python 3.6.4 32-bit version and appending MEGA_STR strings (which contain one million characters each) onto the end of an array until the process catches a MemoryError:,Sure enough, executing alloc_max_str() results in a raised MemoryError after a relatively short execution period:

To test this stuff out we’ll be using the psutil to retrieve information about the active process, and specifically, the psutil.virtual_memory() method, which provides current memory usage stats when invoked. This information is printed within the print_memory_usage() function:

def print_memory_usage():
    """Prints current memory usage stats.
    See: https://stackoverflow.com/a/15495136

    :return: None
    """
    total, available, percent, used, free = psutil.virtual_memory()
    total, available, used, free = total / MEGA, available / MEGA, used / MEGA, free / MEGA
    proc = PROCESS.memory_info()[1] / MEGA
    print('process = %s total = %s available = %s used = %s free = %s percent = %s'
          % (proc, total, available, used, free, percent))

We’ll start by using the Python 3.6.4 32-bit version and appending MEGA_STR strings (which contain one million characters each) onto the end of an array until the process catches a MemoryError:

PROCESS = psutil.Process(os.getpid())
MEGA = 10 ** 6
MEGA_STR = ' ' * MEGA

def alloc_max_array():
    """Allocates memory for maximum array.
    See: https://stackoverflow.com/a/15495136

    :return: None
    """
    collection = []
    while True:
        try:
            collection.append(MEGA_STR)
        except MemoryError as error:
            # Output expected MemoryErrors.
            log_exception(error)
            break
        except Exception as exception:
            # Output unexpected Exceptions.
            log_exception(exception, False)
    print('Maximum array size:', len(collection) * 10)
    print_memory_usage()

def log_exception(exception: BaseException, expected: bool = True):
    """Prints the passed BaseException to the console, including traceback.

    :param exception: The BaseException to output.
    :param expected: Determines if BaseException was expected.
    """
    output = "[{}] {}: {}".format('EXPECTED' if expected else 'UNEXPECTED', type(exception).__name__, exception)
    print(output)
    exc_type, exc_value, exc_traceback = sys.exc_info()
    traceback.print_tb(exc_traceback)    

After we run out of memory and break out of the loop we output the memory usage of the array, along with overall memory usage stats. The result of running this function is the following output:

process = 14.577664 total = 17106.767872 available = 9025.814528 used = 8080.953344 free = 9025.814528 percent = 47.2

[EXPECTED] MemoryError: 
  File "D:/work/Airbrake.io/Exceptions/Python/BaseException/Exception/MemoryError/main.py", line 33, in alloc_max_array
    collection.append(MEGA_STR)

Maximum array size: 1074655510

process = 446.603264 total = 17106.767872 available = 8769.028096 used = 8337.739776 free = 8769.028096 percent = 48.7

This shows our base memory usage at the top, and the array size we created at the bottom. As expected, after about 15 seconds of execution on my system we experienced a MemoryError. The alloc_max_str() function test creates a large string instead of an array, but we should see similar results:

def alloc_max_str():
    """Allocates memory for maximum string.
    See: https://stackoverflow.com/a/15495136

    :return: None
    """
    i = 0
    while True:
        try:
            a = ' ' * (i * 10 * MEGA)
            del a
        except MemoryError as error:
            # Output expected MemoryErrors.
            log_exception(error)
            break
        except Exception as exception:
            # Output unexpected Exceptions.
            log_exception(exception, False)
        i += 1
    max_i = i - 1
    print('Maximum string size:', (max_i * 10 * MEGA))
    print_memory_usage()

Sure enough, executing alloc_max_str() results in a raised MemoryError after a relatively short execution period:

[EXPECTED] MemoryError: 
  File "D:/work/Airbrake.io/Exceptions/Python/BaseException/Exception/MemoryError/main.py", line 54, in alloc_max_str
    a = ' ' * (i * 10 * MEGA)

Maximum string size: 1110000000

process = 14.966784 total = 17106.767872 available = 9240.141824 used = 7866.626048 free = 9240.141824 percent = 46.0

Answer by Tadeo Hudson

I am running orator on windows/ python 2.7, and my model looks like:,Note that I was running it from the python console both for windows and linux,I am not using any migration file.
I even replayed this scenario with python 3 on Ubuntu 14.04 and got the same error when I run,Restaurant.area or Restaurant.area()

class Area(Model):
    pass

class Restaurant(Model):

    @has_one()
    def area(self):
        return Area

Answer by Lukas Barrera

Decoupling the Python stack from the C stack,RecursionOverflow exception,StackOverflow exception,Making Python-to-Python calls without consuming the C stack

If this PEP is accepted, then the following program will run safely to completion:

sys.setrecursionlimit(1_000_000)

def f(n):
    if n:
        f(n-1)

f(500_000)

and the following program will raise a StackOverflow, without causing a VM crash:

sys.setrecursionlimit(1_000_000)

class X:
    def __add__(self, other):
        return self + other

X() + 1

Answer by Dexter Avery

^ a b What is the difference between a segmentation fault and a stack overflow? at StackOverflow
,The most-common cause of stack overflow is excessively deep or infinite recursion, in which a function calls itself so many times that the space needed to store the variables and information associated with each call is more than can fit on the stack.[2]
,On a C implementation with 8 byte double-precision floats, the declared array consumes 8 megabytes of data; if this is more memory than is available on the stack (as set by thread creation parameters or operating system limits), a stack overflow will occur.
,Both pow(base, exp) functions above compute an equivalent result, however, the one on the left is prone to causing a stack overflow because tail-call optimization is not possible for this function. During execution, the stack for these functions will look like this:

int foo() 
{
     return foo();
}

Answer by Cora Fletcher

Ask Ubuntu is a question and answer site for Ubuntu users and developers. It only takes a minute to sign up.,Stack Overflow em Português,Stack Overflow en español,Stack Overflow на русском

Get the swap space ready:

$ sudo fallocate -l 2G /extra.swap
$ sudo chmod 0600 /extra.swap
$ sudo mkswap /extra.swap

Now check your memory

$ free -mh

and now add the swap space to your system

$ sudo swapon /extra.swap

If you check the free memory again you should see the increase in your swap memory.

$ df -h

If you want to disable the extra swap space, for example to remove the file, you can do:

$ sudo swapoff /extra.swap

Answer by Heidi Miller

Why do I get a stack overflow and not a recursion error, as I was expecting?,Edit: Unintended use of Python ahead, but here’s another way to get a stack overflow:,Youre reaching an actual stack overflow: https://en.wikipedia.org/wiki/Stack_overflow,overflows the stack, while

Usually when you use a function recursively (I think) 1000 times, it will error: «Maximum recursion depth of 999 reached». However, when I was trying to break my program I got this error instead:

Fatal Python error: Cannot recover from stack overflow.

Current thread 0x00007fc9f48c9700 (most recent call first):
  File "./player_guesses.py", line 24 in takeGuess
  File "./player_guesses.py", line 27 in takeGuess
  File "./player_guesses.py", line 27 in takeGuess
.
.
.
  File "./player_guesses.py", line 27 in takeGuess
  ...





Aborted (core dumped)

The function that was recursing was this:

#In player_guesses.py
def takeGuess():
    guess = input("Take a guess: ")
    if len(guess) != 3 or not guess.isdigit():
        print("The guess '{}' is not valid, try again!".format(guess))
        return takeGuess()
    else:
        return guess

Edit: Unintended use of Python ahead, but here’s another way to get a stack overflow:

def rec():
    try:
        rec():
    except RecursionError:
        rec()

Впервые я столкнулся с Memory Error, когда работал с огромным массивом ключевых слов. Там было около 40 млн. строк, воодушевленный своим гениальным скриптом я нажал Shift + F10 и спустя 20 секунд получил Memory Error.

Memory Error — исключение вызываемое в случае переполнения выделенной ОС памяти, при условии, что ситуация может быть исправлена путем удаления объектов. Оставим ссылку на доку, кому интересно подробнее разобраться с этим исключением и с формулировкой. Ссылка на документацию по Memory Error.

Если вам интересно как вызывать это исключение, то попробуйте исполнить приведенный ниже код.

print('a' * 1000000000000)

Почему возникает MemoryError?

В целом существует всего лишь несколько основных причин, среди которых:

  • 32-битная версия Python, так как для 32-битных приложений Windows выделяет лишь 4 гб, то серьезные операции приводят к MemoryError
  • Неоптимизированный код
  • Чрезмерно большие датасеты и иные инпут файлы
  • Ошибки в установке пакетов

Как исправить MemoryError?

Ошибка связана с 32-битной версией

Тут все просто, следуйте данному гайдлайну и уже через 10 минут вы запустите свой код.

Как посмотреть версию Python?

Идем в cmd (Кнопка Windows + R -> cmd) и пишем python. В итоге получим что-то похожее на

Python 3.8.8 (tags/v3.8.8:024d805, Feb 19 2021, 13:18:16) [MSC v.1928 64 bit (AMD64)]

Нас интересует эта часть [MSC v.1928 64 bit (AMD64)], так как вы ловите MemoryError, то скорее всего у вас будет 32 bit.

Как установить 64-битную версию Python?

Идем на официальный сайт Python и качаем установщик 64-битной версии. Ссылка на сайт с официальными релизами. В скобках нужной нам версии видим 64-bit. Удалять или не удалять 32-битную версию — это ваш выбор, я обычно удаляю, чтобы не путаться в IDE. Все что останется сделать, просто поменять интерпретатор.

Идем в PyCharm в File -> Settings -> Project -> Python Interpreter -> Шестеренка -> Add -> New environment -> Base Interpreter и выбираем python.exe из только что установленной директории. У меня это

C:/Users/Core/AppData/LocalPrograms/Python/Python38

Все, запускаем скрипт и видим, что все выполняется как следует.

Оптимизация кода

Пару раз я встречался с ситуацией когда мои костыли приводили к MemoryError. К этому приводили избыточные условия, циклы и буферные переменные, которые не удаляются после потери необходимости в них. Если вы понимаете, что проблема может быть в этом, вероятно стоит закостылить пару del, мануально удаляя ссылки на объекты. Но помните о том, что проблема в архитектуре вашего проекта, и по настоящему решить эту проблему можно лишь правильно проработав структуру проекта.

Явно освобождаем память с помощью сборщика мусора

В целом в 90% случаев проблема решается переустановкой питона, однако, я  просто обязан рассказать вам про библиотеку gc. В целом почитать про Garbage Collector стоит отдельно на авторитетных ресурсах в статьях профессиональных программистов. Вы просто обязаны знать, что происходит под капотом управления памятью. GC — это не только про Python, управление памятью в Java и других языках базируется на технологии сборки мусора. Ну а вот так мы можем мануально освободить память в Python:

Если ты их кладёшь в список, очевидно что ты ограничен размером памяти. Поэтому очевидно что не нужно класть их в список, а нужно обрабатывать по одному.

slovazap ★★★★★

(07.11.19 22:25:31 MSK)

  • Показать ответ
  • Ссылка

Ответ на:

комментарий
от slovazap 07.11.19 22:25:31 MSK

Поподробей можно?

Сколько элементов можно положить в список на python x32?
Сколько элементов можно положить в список на python x64?
Какие еще нъюансы есть?

KRex

(07.11.19 22:40:04 MSK)

  • Показать ответы
  • Ссылка

Ответ на:

комментарий
от Jopich1 07.11.19 22:30:06 MSK

Ответ на:

В курсе
от KRex 07.11.19 22:40:35 MSK

Re: В курсе

import sys

KiB = 1024
MiB = 1024 * KiB
GiB = 1024 * MiB

with open('/proc/meminfo') as f:
    ram = f.readline() 
    ram = ram[ram.index(' '):ram.rindex(' ')].strip()    
    ram = int(ram) * KiB / GiB 
    
required = sys.getsizeof(42) * 1_000_000_000 / GiB

print('Надо:', required, 'GiB')
print('Есть:', ram, 'GiB')

if required > ram:
    print('У тебя совесть есть, сцуко?!')

anonymous

(07.11.19 23:02:05 MSK)

  • Показать ответы
  • Ссылка

Ответ на:

Re: В курсе
от anonymous 07.11.19 23:02:05 MSK

os.sysconf('SC_PAGE_SIZE')*os.sysconf('SC_PHYS_PAGES')

anonymous

(07.11.19 23:14:46 MSK)

  • Показать ответ
  • Ссылка

Ответ на:

комментарий
от anonymous 07.11.19 23:14:46 MSK

Спасибо.

anonymous

(07.11.19 23:16:03 MSK)

  • Ссылка

Неизвестно даже приблизительно — зависит от платформы, аллокатора, настроек системы, фрагментации кучи, объектов которые вы собираетесь туда класть (а под них самих тоже нужна память) и много чего ещё.

slovazap ★★★★★

(07.11.19 23:19:59 MSK)

  • Ссылка

python как справиться с memory error?

Это не проблема питона, это проблема системы. Нужно разрешить memory overcommit (выставить в единицу) на используемой системе.

А memory error можешь просто обрабатывать как исключение.

anonymous

(08.11.19 03:44:04 MSK)

  • Показать ответ
  • Ссылка

Какие еще нъюансы есть

Если физической оперативки не хватит программа зависнет и придёт OOM killer, или не придёт… Если элементов слишком много, то работать надо с файлами или удалять их… Я вот с CSV переодически сталкиваюсь, которые по 10 Гб + и в оперативке будут в разобранном виде весить гигов 500-600. Работаю с файлами в результате, читаю обрабатываю 1000 записей, потом опять читаю. А что поделать? И да, про БД знаю, но иногда лучше файл руками читать, чем с БД возиться.

peregrine ★★★★★

(08.11.19 03:47:44 MSK)



Последнее исправление: peregrine 08.11.19 03:51:16 MSK
(всего

исправлений: 2)

  • Ссылка

Ответ на:

Re: В курсе
от anonymous 07.11.19 23:02:05 MSK

Re: В курсе

with open(‘/proc/meminfo’) as f:

Это не даст хорошего результата во многих случаях: meminfo не показываем объем свободной виртуальной памяти. memory error возникает при невозможности выделить виртуальную, а не при нехватке физической памяти.

anonymous

(08.11.19 03:48:13 MSK)

  • Показать ответ
  • Ссылка

Ответ на:

Re: В курсе
от anonymous 08.11.19 03:48:13 MSK

Re: В курсе

Это не даст хорошего результата во многих случаях: meminfo не показываем объем свободной виртуальной памяти. memory error возникает при невозможности выделить виртуальную, а не при нехватке физической памяти.

Какого «хорошего результата» ты ждёшь? Это даст примерный объём физической памяти, как и задумано. Чел пытается аллоцировать список на 25 гигабайтов. Невозможность выделить виртуальную память немного предсказуема, как следсвие острой нехватки физической.

О существовании величины «свободная виртуальная память» и о том, как её измерять, можно поспорить отдельно.

anonymous

(08.11.19 04:58:02 MSK)

  • Показать ответ
  • Ссылка

Ответ на:

Re: В курсе
от anonymous 08.11.19 04:58:02 MSK

Re: В курсе

О существовании величины «свободная виртуальная память» и о том, как её измерять, можно поспорить отдельно.

Если оверкоммит запрещен, то легко измеряется.

Невозможность выделить виртуальную память немного предсказуема

Именно немного. Физической памяти может быть под ноль, но memory error не произойдет по причине разрешения оверкоммита. И наоброт, при запрете оверкоммита может призойти ошибка выделения задолго до того как физическая память будет исчерпана.

anonymous

(08.11.19 06:31:09 MSK)

  • Показать ответ
  • Ссылка

Ответ на:

Re: В курсе
от anonymous 08.11.19 06:31:09 MSK

Re: В курсе

Если оверкоммит запрещен, то легко измеряется.

Если оверкоммит запрещён, то ты будешь легко измерять свободную физическую.

Именно немного. Физической памяти может быть под ноль, но memory error не произойдет по причине разрешения оверкоммита.

Произойдёт, потому что он в неё пишет.

И наоброт, при запрете оверкоммита может призойти ошибка выделения задолго до того как физическая память будет исчерпана.

Может произойти и задолго. Только влез ты с этим замечанием не в тему, потому что чел явно исчерпывает физическую память, а цель кода, который ты полез поправлять – наглядно это продемонстрировать.

anonymous

(08.11.19 07:34:02 MSK)

  • Показать ответ
  • Ссылка

Ответ на:

Re: В курсе
от anonymous 08.11.19 07:34:02 MSK

Re: В курсе

Если оверкоммит запрещён, то ты будешь легко измерять свободную физическую.

              CommitLimit %lu (since Linux 2.6.10)
                     This is the total amount of memory currently available
                     to be allocated on the system, expressed in kilobytes.
                     This limit is adhered to only if strict overcommit
                     accounting is enabled (mode 2 in /proc/sys/vm/overcom‐
                     mit_memory).  The limit is calculated according to the
                     formula described under /proc/sys/vm/overcommit_memory.
                     For further details, see the kernel source file Docu‐
                     mentation/vm/overcommit-accounting.rst.

              Committed_AS %lu
                     The amount of memory presently allocated on the system.
                     The committed memory is a sum of all of the memory
                     which has been allocated by processes, even if it has
                     not been "used" by them as of yet.  A process which
                     allocates 1GB of memory (using malloc(3) or similar),
                     but touches only 300MB of that memory will show up as
                     using only 300MB of memory even if it has the address
                     space allocated for the entire 1GB.

                     This 1GB is memory which has been "committed" to by the
                     VM and can be used at any time by the allocating appli‐
                     cation.  With strict overcommit enabled on the system
                     (mode 2 in /proc/sys/vm/overcommit_memory), allocations
                     which would exceed the CommitLimit will not be permit‐
                     ted.  This is useful if one needs to guarantee that
                     processes will not fail due to lack of memory once that
                     memory has been successfully allocated.

О бредовости остальных ваших тезисов догадайтесь сами.

anonymous

(08.11.19 07:57:41 MSK)

  • Показать ответ
  • Ссылка

Ответ на:

Re: В курсе
от anonymous 08.11.19 07:57:41 MSK

Re: В курсе

Если ты нашёл способ писать в память больше данных, чем в неё влазит, то поделись с человечеством, пожалуйста.

Если нет – догадываться, что не так в голове очередного чудака, мне лень.

anonymous

(08.11.19 08:05:15 MSK)

  • Показать ответ
  • Ссылка

Ответ на:

Re: В курсе
от anonymous 08.11.19 08:05:15 MSK

Re: В курсе

писать в память больше данных, чем в неё влазит

Речь не об этом. Речь о том, что Commitet_AS (выделенная) может быть больше, чем физическая (MemTotal).

Можно иметь 4 гига физической, 2 гига свопа, и 12 гиг выделенной памяти. Для возникновения MemoryError процесс должен попытаться выделить ВИРТУАльНУЮ память при ее ограниченности. Если процесс уперся в лимит физической памяти раньше, чем в лимит виртуальной, то он не упадет на MemoryError — тут будет или зависание системы, или приход оом киллера, в редком случае возможен OSError.

anonymous

(08.11.19 11:16:12 MSK)

  • Ссылка

Ответ на:

комментарий
от anonymous 08.11.19 03:44:04 MSK

Это не проблема питона, это проблема питонокодера

fixed. Ему говорят как делать правильно, он — нет, хочу научиться говнокодить.

anonymous

(08.11.19 11:39:32 MSK)

  • Ссылка

Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.

SW Developer

97 / 93 / 81

Регистрация: 10.01.2016

Сообщений: 659

Записей в блоге: 13

1

22.01.2021, 14:14. Показов 1538. Ответов 15

Метки нет (Все метки)


Добрый день!

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
from memory_profiler import profile
import timeit
import math
import sys
 
print(sys.getrecursionlimit())
sys.setrecursionlimit(10000)
print(sys.getrecursionlimit())
 
 
def timer(function):
    def new_function(*args, **kwargs):
        start_time = timeit.default_timer()
        ret = function(*args, **kwargs)
        elapsed = timeit.default_timer() - start_time
        print(f'Время выполнения функции: {elapsed:.04f}')
        return ret
    return new_function
 
 
num = 5000
 
 
@timer
@profile
def recursion(n):
    def factorial(x):
        if x == 1:
            return x
        else:
            return x * factorial(x - 1)
 
    print(f'Факториал числа {num}: {factorial(n)}')
 
 
@timer
@profile
def for_factorial(n):
    fact = 1
    for i in range(2, n+1):
        fact *= i
    print(f'Факториал числа {n}: {fact}')
 
 
@timer
@profile
def math_factorial(n):
    fact = math.factorial(n)
    print(f'Факториал числа {n}: {fact}')
 
 
recursion(num)
for_factorial(num)
math_factorial(num)

Почему работает только при 4000 итераций?

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

22.01.2021, 14:14

15

Эксперт Python

4606 / 2027 / 359

Регистрация: 17.03.2012

Сообщений: 10,081

Записей в блоге: 6

22.01.2021, 14:42

2

«Memoryerror» кагбэ намекает, что у вас слишком большие аппетиты.



0



97 / 93 / 81

Регистрация: 10.01.2016

Сообщений: 659

Записей в блоге: 13

22.01.2021, 14:47

 [ТС]

3

Так вроде бы указал:

Цитата
Сообщение от SW Developer
Посмотреть сообщение

sys.setrecursionlimit(10000)

16 Gb RAM мало?



0



Эксперт Python

4606 / 2027 / 359

Регистрация: 17.03.2012

Сообщений: 10,081

Записей в блоге: 6

22.01.2021, 16:03

4

SW Developer,
Тут же не накладные расходы на рекурсию, а запрос памяти внутри самой процедуры. А факториал растёт очень быстро. Так что вполне возможно.



0



97 / 93 / 81

Регистрация: 10.01.2016

Сообщений: 659

Записей в блоге: 13

22.01.2021, 17:21

 [ТС]

5

dondublon, что-то не сходится. При глубине рекурсии 1000 объем памяти занимает 16.7 MiB, при 4000 — 19.6 MiB. Хотите сказать, что при 10000 не хватит 16 Гигабайт?



0



Эксперт Python

5403 / 3827 / 1214

Регистрация: 28.10.2013

Сообщений: 9,554

Записей в блоге: 1

22.01.2021, 17:50

6

Python выбрасывает MemoryError заранее — когда понимает, что ее ему не хватит.
Чему вы удивляетесь?
Длинная арифметика в Python встроенная, но, увы, неэффективная, в сравнении с компилируемыми языками.
Сколько будет цифр в факториале 5000? Больше 16 тыс. А теперь представьте сколько таких чиселок ему приходится держать в памяти на каждый ход рекурсии…



0



Эксперт Python

4606 / 2027 / 359

Регистрация: 17.03.2012

Сообщений: 10,081

Записей в блоге: 6

22.01.2021, 17:57

7

SW Developer, я бы на вашем месте попробовал построить график, для начала — по тысяче, при приближении к порогу (на котром вываливается) — поточнее. Факториал растёт очень быстро.



0



3425 / 2069 / 558

Регистрация: 02.09.2015

Сообщений: 5,298

22.01.2021, 18:27

8

Цитата
Сообщение от SW Developer
Посмотреть сообщение

sys.setrecursionlimit(10000)

Поставьте больше лимит — у вас переполняется стек вызовов функций.



0



97 / 93 / 81

Регистрация: 10.01.2016

Сообщений: 659

Записей в блоге: 13

22.01.2021, 19:07

 [ТС]

9

Garry Galler,

Цитата
Сообщение от Garry Galler
Посмотреть сообщение

Сколько будет цифр в факториале 5000? Больше 16 тыс.

думаю, что намного-намного больше, если верить Википедии.



0



Garry Galler

Эксперт Python

5403 / 3827 / 1214

Регистрация: 28.10.2013

Сообщений: 9,554

Записей в блоге: 1

22.01.2021, 19:18

10

Цитата
Сообщение от SW Developer
Посмотреть сообщение

думаю, что намного-намного больше,

Python
1
2
3
>>> len(str(math.factorial(5000)))
16326
>>>



1



SW Developer

97 / 93 / 81

Регистрация: 10.01.2016

Сообщений: 659

Записей в блоге: 13

22.01.2021, 19:33

 [ТС]

11

Arsegg,

Цитата
Сообщение от Arsegg
Посмотреть сообщение

Поставьте больше лимит — у вас переполняется стек вызовов функций.

Это не работает, результат такой же — 4000!.

Добавлено через 4 минуты
Garry Galler,

Цитата
Сообщение от Garry Galler
Посмотреть сообщение

Python
1
2
3
>>> len(str(math.factorial(5000)))
16326
>>>

не правильно вас понял.)

Какой диапазон типа INT?

Добавлено через 8 минут
dondublon,

Цитата
Сообщение от dondublon
Посмотреть сообщение

SW Developer, я бы на вашем месте попробовал построить график

, график зависимости N от

Python
1
len(str(math.factorial(N)))

?



0



Эксперт Python

5403 / 3827 / 1214

Регистрация: 28.10.2013

Сообщений: 9,554

Записей в блоге: 1

22.01.2021, 19:41

12

Цитата
Сообщение от SW Developer
Посмотреть сообщение

Какой диапазон типа INT?

Размер ОЗУ вашего компьютера. У Python нет размерности числовых типов и нет деления на short, long и long long.
И в Python крайне опрометчиво что-то вычислять рекурсией: в других ЯП вы бы получили цикл вместо рекурсии (хвостовая оптимизация). В Python ее нет. По историческим причинам и личной неприязни Гвидо к рекурсии.



1



Эксперт Python

4606 / 2027 / 359

Регистрация: 17.03.2012

Сообщений: 10,081

Записей в блоге: 6

24.01.2021, 21:33

13

SW Developer, график используемой памяти в зависимости от N (аргумент факториала). Явно где-то между 5000 и 4000 критическое значение. Надо посмотреть, как ведёт себя память вблизи.



0



97 / 93 / 81

Регистрация: 10.01.2016

Сообщений: 659

Записей в блоге: 13

25.01.2021, 11:24

 [ТС]

14

Цитата
Сообщение от dondublon
Посмотреть сообщение

график используемой памяти в зависимости от N (аргумент факториала)

dondublon, не подскажите, где копать, чтобы создать такую зависимость?



0



Эксперт Python

4606 / 2027 / 359

Регистрация: 17.03.2012

Сообщений: 10,081

Записей в блоге: 6

25.01.2021, 11:36

15

SW Developer, быстрее вручную, чем огород городить. Бисекцией.
4000 работает, 5000 вылетает — значит, считаем 4500. Падает — значит, 4250, не падает — 4750.
Как найдёте падучую границу — хоть три значения до неё посмотрите, убедиться, что взлетает.



1



97 / 93 / 81

Регистрация: 10.01.2016

Сообщений: 659

Записей в блоге: 13

25.01.2021, 11:56

 [ТС]

16

dondublon, понятно, бинарный поиск.
Спасибо.



0



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

25.01.2021, 11:56

Помогаю со студенческими работами здесь

Stack overflow
Реализовал структуру данных стек на связном списке, очистку решил возложить на деструкторы узлов,…

Stack overflow.
У меня в программе есть реверсивная функция (много параметров) она вызывает себя очень много раз….

БД Stack Overflow
1. Составить запрос к БД stackoverfow. Результат запроса должен содержать
список имен…

stack overflow
Всем привет.
пишу
void test() {

try {
cout << "test n";
test();
}
catch(exception…

Stack overflow
После создания вычисляемого поля через несколько запусков приложения начинает выдавать такое…

Stack overflow
Еще раз здрасьте=)
Простите за дубляж тем, но последние сообщения тут, видимо, читают редко, а мне…

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:

16

Автор оригинала: Team Python Pool.

Что такое Ошибка памяти?

Ошибка памяти Python или на языке непрофессионалов-это именно то, что означает, что у вас закончилась память в вашей оперативной памяти для выполнения вашего кода.

Когда эта ошибка возникает, это, скорее всего, потому, что вы загрузили все данные в память. Для больших наборов данных вы захотите использовать пакетную обработку . Вместо того чтобы загружать весь набор данных в память, вы должны хранить свои данные на жестком диске и получать к ним доступ пакетами.

Ошибка памяти означает, что ваша программа исчерпала память. Это означает, что ваша программа каким-то образом создает слишком много объектов. В вашем примере вы должны искать части вашего алгоритма, которые могут потреблять много памяти.

Если у операции заканчивается память, это называется ошибкой памяти .

Типы ошибок памяти Python

Неожиданная ошибка памяти в Python

Если вы получаете неожиданную ошибку памяти Python и думаете, что у вас должно быть много доступных ОЗУ, это может быть связано с тем, что вы используете 32-битную установку python .

Простое решение для неожиданной ошибки памяти Python

У вашей программы заканчивается виртуальное адресное пространство. Скорее всего, потому, что вы используете 32-битную версию Python. Поскольку Windows (как и большинство других ОС) ограничивает 32-разрядные приложения до 2 ГБ адресного пространства пользовательского режима.

Мы рекомендуем вам установить 64-битную версию Python (если вы можете, я бы рекомендовал обновить ее до Python 3 по другим причинам); она будет использовать больше памяти, но тогда у нее будет доступ к большему объему памяти (и больше физической оперативной памяти).

Проблема в том, что 32-битный python имеет доступ только к ~4 ГБ оперативной памяти. Это может уменьшиться еще больше, если ваша операционная система 32-разрядная, из-за накладных расходов операционной системы.

Например, в Python 2 функция zip принимает несколько итераций и возвращает один итератор кортежей. Во всяком случае, каждый элемент итератора нужен нам один раз для циклирования. Таким образом, нам не нужно хранить все элементы в памяти на протяжении всего цикла. Поэтому было бы лучше использовать izip, который извлекает каждый элемент только на следующих итерациях. Python 3 zip по умолчанию функционирует как izip.

Должен Читать: Python Print Без Новой Строки

Ошибка памяти Python Из-за набора данных

Как и в случае с 32-битной и 64-битной версиями, другой возможностью может быть размер набора данных, если вы работаете с большим набором данных.Загрузка большого набора данных непосредственно в память и выполнение над ним вычислений и сохранение промежуточных результатов этих вычислений могут быстро заполнить вашу память. Функции генератора очень пригодятся, если это ваша проблема. Многие популярные библиотеки python, такие как Keras и TensorFlow, имеют специальные функции и классы для генераторов.

Ошибка памяти Python Из – за неправильной установки Python

Неправильная установка пакетов Python также может привести к ошибке памяти . На самом деле, прежде чем решить проблему, Мы установили на windows вручную python 2.7 и пакеты, которые мне были нужны, после того, как возились почти два дня, пытаясь выяснить, в чем проблема, Мы переустановили все с помощью Conda , и проблема была решена.

Мы предполагаем, что Honda устанавливает лучшие пакеты управления памятью, и это было главной причиной. Таким образом, вы можете попробовать установить пакеты Python с помощью Conda, это может решить проблему ошибки памяти.

Ошибка нехватки памяти в Python

Большинство платформ возвращают “Out of Memory error”, если попытка выделить блок памяти завершается неудачей, но первопричина этой проблемы очень редко имеет какое-либо отношение к тому, что действительно “out of memory”.” Это происходит потому, что почти в каждой современной операционной системе диспетчер памяти с радостью использует доступное место на жестком диске в качестве места для хранения страниц памяти, которые не помещаются в оперативную память; ваш компьютер обычно может выделять память до тех пор, пока диск не заполнится, и это может привести к ошибке Python Out of Memory(или к превышению лимита подкачки; в Windows см. раздел Свойства системы > Параметры производительности > Дополнительно > Виртуальная память).

Что еще хуже, каждое активное выделение в адресном пространстве программы может вызвать “фрагментацию”, которая может предотвратить будущие выделения, разбивая доступную память на куски, которые по отдельности слишком малы, чтобы удовлетворить новое выделение одним непрерывным блоком.

1 Если 32-битное приложение имеет установленный флаг LARGEADDRESSAWARE, оно имеет доступ к полным 4 гб адресного пространства при работе на 64-битной версии Windows.

2 До сих пор четыре читателя написали, чтобы объяснить, что флаг gcAllowVeryLargeObjects устраняет это ограничение .NET. Это не так. Этот флаг позволяет объектам, которые занимают более 2 Гб памяти, но он не позволяет одномерному массиву содержать более 2^31 записей.

Как я могу явно освободить память в Python?

Если вы написали программу Python, которая действует на большой входной файл, чтобы создать несколько миллионов объектов, представляющих собой, и это занимает тонны памяти, и вам нужен лучший способ сказать Python, что вам больше не нужны некоторые данные, и они могут быть освобождены?

Простой ответ на эту проблему:

Принудительно вызовите сборщик мусора для освобождения несвязанной памяти с помощью gc.collect().

Как показано ниже:

импорт gc

gc.collect()

Ошибка памяти в Python, пул PythonОшибка памяти в Python, пул Python

Ошибка памяти в Python, когда 50+ГБ свободны и используют 64-битный python?

В некоторых операционных системах существуют ограничения на объем оперативной памяти, который может обрабатывать один процессор. Таким образом, даже если есть достаточно свободной оперативной памяти, ваш единственный поток на одном ядре) не может взять больше. Но я не знаю, действительно ли это для вашей версии Windows.

Как вы устанавливаете использование памяти для программ python?

Python использует сборку мусора и встроенное управление памятью, чтобы гарантировать, что программа использует только столько оперативной памяти, сколько требуется. Поэтому, если вы специально не пишете свою программу таким образом, чтобы увеличить использование памяти, например, создавая базу данных в оперативной памяти, Python использует только то, что ему нужно.

В связи с этим возникает вопрос: почему вы хотите использовать больше оперативной памяти? Идея большинства программистов сводится к минимизации использования ресурсов.

если вы хотите ограничить использование памяти виртуальной машины python, вы можете попробовать следующее:1、Linux, команда ulimit для ограничения использования памяти на python2、вы можете использовать модуль ресурсов для ограничения использования памяти программы; если вы хотите ускорить программу ur, хотя и дать больше памяти приложению ur, вы можете попробовать следующее:1threading, multiprocessing2pypy3pysco только на python 2.5

Как установить ограничения на использование памяти и процессора

Чтобы ограничить использование памяти или процессора запущенной программой. Так что мы не столкнемся с какой-либо ошибкой памяти. Для этого можно использовать модуль ресурсов , и таким образом обе задачи могут быть выполнены очень хорошо, как показано в приведенном ниже коде:

Код #1: Ограничение процессорного времени

# importing libraries 
import signal 
import resource 
import os 

# checking time limit exceed 
def time_exceeded(signo, frame): 
	print("Time's up !") 
	raise SystemExit(1) 

def set_max_runtime(seconds): 
	# setting up the resource limit 
	soft,.getrlimit(resource.RLIMIT_CPU) 
	resource.setrlimit(resource.RLIMIT_CPU, (seconds, hard)) 
	signal.signal(signal.SIGXCPU, time_exceeded) 

# max run time of 15 millisecond 
if __name__: 
	set_max_runtime(15) 
	while True: 
		pass

Код #2: Чтобы ограничить использование памяти, код устанавливает ограничение на общее адресное пространство

# using resource 
import resource 

def limit_memory(maxsize): 
	soft,.getrlimit(resource.RLIMIT_AS) 
	resource.setrlimit(resource.RLIMIT_AS, (maxsize, hard))

Способы обработки ошибок памяти Python и больших файлов данных

1. Выделите Больше Памяти

Некоторые инструменты или библиотеки Python могут быть ограничены конфигурацией памяти по умолчанию.

Проверьте, можете ли вы перенастроить свой инструмент или библиотеку, чтобы выделить больше памяти.

То есть платформа, предназначенная для обработки очень больших наборов данных, которая позволяет использовать преобразования данных и алгоритмы машинного обучения поверх нее.

Хорошим примером является Weka, где вы можете увеличить объем памяти в качестве параметра при запуске приложения.

2. Работа с меньшим образцом

Вы уверены, что вам нужно работать со всеми данными?

Возьмите случайную выборку данных, например первые 1000 или 100 000 строк. Используйте эту меньшую выборку для проработки вашей проблемы, прежде чем подгонять окончательную модель ко всем вашим данным (используя прогрессивные методы загрузки данных).

Я думаю, что это хорошая практика в целом для машинного обучения, чтобы дать вам быструю выборочную проверку алгоритмов и поворот результатов.

Вы также можете рассмотреть возможность проведения анализа чувствительности объема данных, используемых для подгонки одного алгоритма, по сравнению с навыком модели. Возможно, существует естественная точка уменьшения отдачи, которую вы можете использовать в качестве эвристического размера вашей меньшей выборки.

3. Используйте компьютер с большим объемом памяти

Вам обязательно работать на компьютере?

Возможно, вы сможете получить доступ к гораздо большему компьютеру с на порядок большим объемом памяти.

Например, хорошим вариантом является аренда вычислительного времени на облачном сервисе, таком как Amazon Web Services, который предлагает машины с десятками гигабайт оперативной памяти менее чем за доллар США в час.

4. Используйте реляционную базу данных

Реляционные базы данных обеспечивают стандартный способ хранения и доступа к очень большим наборам данных.

Внутренне данные, хранящиеся на диске, могут быть постепенно загружены пакетами и могут быть запрошены с помощью стандартного языка запросов (SQL).

Бесплатные инструменты базы данных с открытым исходным кодом, такие как href=”https://www.mysql.com/”>MySQL или href=”https://www.postgresql.org/”>Postgres можно использовать, и большинство (все?) языков программирования и многие инструменты машинного обучения могут подключаться непосредственно к реляционным базам данных. Вы также можете использовать легкий подход, например href=”https://www.sqlite.org/”>SQLite. href=”https://www.mysql.com/”>MySQL или href=”https://www.postgresql.org/”>Postgres можно использовать, и большинство (все?) языков программирования и многие инструменты машинного обучения могут подключаться непосредственно к реляционным базам данных. Вы также можете использовать легкий подход, например href=”https://www.sqlite.org/”>SQLite. href=”https://www.postgresql.org/”>Postgres можно использовать, и большинство (все?) языков программирования и многие инструменты машинного обучения могут подключаться непосредственно к реляционным базам данных. Вы также можете использовать легкий подход, например href=”https://www.sqlite.org/”>SQLite. href=”https://www.sqlite.org/”>SQLite.

5. Используйте платформу больших данных

В некоторых случаях вам может потребоваться прибегнуть к платформе больших данных.

Резюме

В этом посте вы обнаружили ряд тактик и способов, которые можно использовать при работе с ошибкой памяти Python.

Есть ли другие методы, о которых вы знаете или пробовали?Поделитесь ими в комментариях ниже.

Вы пробовали какой-нибудь из этих методов?Дайте мне знать в комментариях.

Если ваша проблема все еще не решена и вам нужна помощь относительно Python Memory Error. Прокомментируйте ниже, мы постараемся решить вашу проблему как можно скорее.

Понравилась статья? Поделить с друзьями:
  • Python memory error out of memory
  • Python math domain error sqrt
  • Python make error
  • Python logic error
  • Python logging level error