首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当加载“太大”的数据,或者没有足够的资源( CPU或内存)时,python的行为是什么?

问当加载“太大”的数据,或者没有足够的资源( CPU或内存)时,python的行为是什么?
EN

Stack Overflow用户
提问于 2020-09-06 05:26:54
回答 1查看 123关注 0票数 0

我正在开发一个程序,它在列表上有一个for循环,有些列表很小,有些列表很大(500k +元素)。当应用程序运行了一段时间后,它会系统地在这个循环中失败,而在之前的迭代中没有失败,列表较小。

为了进行调试,并使用pickle模块,我在进入函数之前转储了列表。当应用程序失败时,刚刚被转储的列表系统地是一个大列表(500k+元素)。获取的文件大小为70MB或更大(二进制模式)。

我知道我有空闲的内存(使用htop,我看到我使用了大约400MB的2 2GB可用内存)。但是CPU经常处于很高的活动百分比(超过60%,有时达到100%)。

当我从文件加载列表时(应用程序停止),我可以毫无问题地运行for迭代。该列表似乎未损坏。

所以,我完全不知道哪里会出问题,除了CPU的活跃度很高。如果Python确实没有足够的资源来工作,它有没有办法告诉我呢?我怎样才能检查这个?它的行为是什么?有没有可能程序停止时没有任何错误消息?

编辑-代码示例

请在下面的代码中找到应用冻结的地方。代码本身可以正常执行。执行的上下文似乎是使代码冻结的原因。

我可以准确地指出,应用程序在名为“百慕大三角”的for循环开始时冻结。我可以使用pickle模块打印数据,但不能在for循环中打印数据。真正奇怪的是,我得到了应该得到打印的文件,但是这个文件(dump_loop.txt)是空的。我觉得这很奇怪,因为要么我应该有0个文件(注意循环开头的os.remove,这意味着我在每次迭代时系统地删除它),要么如果我有一个文件,里面应该有写的东西。

我确认当应用程序运行时(即“正常”,它没有被冻结),这两个文件被正确更新。

谢谢你的帮助!最好的

代码语言:javascript
复制
import os
import json
import pickle
from collections import defaultdict

data = [('1599324732926-0',
         {'data': '{"timestamp":1599324732.767, \
                "receipt_timestamp":1599324732.9256856,\
                "delta":true, \
                "bid":{"338.9":0.06482,"338.67":3.95535}, \
                "ask":{"339.12":2.47578,"339.13":6.43172} \
               }'
         }),
        ('1599324732926-1',
         {'data': '{"timestamp":1599324732.767, \
                "receipt_timestamp":1599324732.9256856,\
                "delta":true, \
                "bid":{"338.9":0.06482,"338.67":3.95535}, \
                "ask":{"339.12":2.47578,"339.13":6.43172} \
               }'
         })]

         
def book_flatten(book: dict, timestamp: float, receipt_timestamp: float, delta: str) -> dict:
    """
    Takes book and returns a list of dict, where each element in the list
    is a dictionary with a single row of book data.

    """
    ret = []
    for side in ('bid', 'ask'):
        for price, data in book[side].items():
            ret.append({'side': side, 'price': price, 'size': data, 'timestamp': timestamp, 'receipt_timestamp': receipt_timestamp, 'delta': delta})
    return ret
         
def read(data, dtype='l2_book', pair='AAPL-USD'):       
    key = f'{dtype}-{pair}'
    if len(data) == 0:
        return []
    print("{!s}: Read {!s} messages from Redis".format(key, len(data)))
    ret = []
    ids=dict()
    last_id=defaultdict(list)

    # 1/Start - Lines added for debug
    # Retrieve the last data before the app freezes
    dump_list='./dump_list.data'
    try:
        os.remove(dump_list)
    except OSError:
        pass
    with open(dump_list, 'wb') as filehandle:
        # store the data as binary data stream
        pickle.dump(data, filehandle)
    dump_loop = './dump_loop.txt'
    total_number = len(data)
    counter=1
    # 1/End

    # The mysterious loop aka Bermuda Triangle
    for update_id, update in data:
        #2/Start - Lines added for debug
        try:
            os.remove(dump_loop)
        except OSError:
            pass
        with open(dump_loop, 'w') as filehandle:
            filehandle.write('Starting new loop for item {!s} over {!s}.\n'.format(counter, total_number))
        #2/End
        if dtype in {'l2_book'}:
            update = json.loads(update['data'])
            update = book_flatten(update, update['timestamp'], update['receipt_timestamp'], update['delta'])
            for u in update:
                for k in ('size', 'amount', 'price', 'timestamp', 'receipt_timestamp'):
                    if k in u:
                        u[k] = float(u[k])
            ret.extend(update)
        elif dtype in {'trades'}:
            for k in ('size', 'amount', 'price', 'timestamp', 'receipt_timestamp', 'bid', 'ask'):
                if k in update:
                    update[k] = float(update[k])
            ret.append(update)
        ids[key] = update_id
        #3/Start - Lines added for debug
        with open(dump_loop, 'a') as filehandle:
            filehandle.write('Loop finished.\n')  
        counter+=1
        #3/End

    last_id[key] = ids[key][-1]
    return ids, last_id, ret
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-09-07 00:18:22

好的,所以有人建议我看一下syslog (作为一个新手,我不知道这个)和‘瞧’!在一次新的测试之后,应用程序my_app在17:45崩溃。以下是syslog在17:45所说的:

代码语言:javascript
复制
Sep  6 17:45:12 cs1 kernel: [67093.681124] oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/user.slice/user-0.slice/session-32.scope,task=cryp>
Sep  6 17:45:12 cs1 kernel: [67093.681180] Out of memory: Killed process 15754 (my_app) total-vm:1752588kB, anon-rss:1332040kB, file-rss:32kB, shmem-rss:0kB, UID:0 pgtables:3144kB oom_sco>
Sep  6 17:45:12 cs1 kernel: [67093.764851] oom_reaper: reaped process 15754 (my_app), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB

所以难怪python什么都不告诉我,它的进程被杀死了…

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63758672

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档