python - 缓存和内存使用

标签 python memory-management python-3.2

我有很多类都做同样的事情:它们在构造期间接收一个标识符(数据库中的 PK),然后从数据库加载。 我试图缓存这些类的实例,以尽量减少对数据库的调用。当缓存达到临界大小时,它应该丢弃那些最近最少访问的缓存对象。

缓存实际上似乎工作正常,但不知何故我无法确定缓存的内存使用情况(在#Next line 没有达到我预期的效果之后的行中)。

到目前为止我的代码:

#! /usr/bin/python3.2

from datetime import datetime
import random
import sys

class Cache:
    instance = None

    def __new__ (cls):
        if not cls.instance:
            cls.instance = super ().__new__ (cls)
            cls.instance.classes = {}
        return cls.instance

    def getObject (self, cls, ident):
        if cls not in self.classes: return None
        cls = self.classes [cls]
        if ident not in cls: return None
        return cls [ident]

    def cache (self, object):
        #Next line doesn't do what I expected
        print (sys.getsizeof (self.classes) )
        if object.__class__ not in self.classes:
            self.classes [object.__class__] = {}
        cls = self.classes [object.__class__]
        cls [object.ident] = (object, datetime.now () )


class Cached:
    def __init__ (self, cache):
        self.cache = cache

    def __call__ (self, cls):
        cls.cache = self.cache

        oNew = cls.__new__
        def new (cls, ident):
            cached = cls.cache ().getObject (cls, ident)
            if not cached: return oNew (cls, ident)
            cls.cache ().cache (cached [0] )
            return cached [0]
        cls.__new__ = new

        def init (self, ident):
            if hasattr (self, 'ident'): return
            self.ident = ident
            self.load ()
        cls.__init__ = init

        oLoad = cls.load
        def load (self):
            oLoad (self)
            self.cache ().cache (self)
        cls.load = load

        return cls


@Cached (Cache)
class Person:
    def load (self):
        print ('Expensive call to DB')
        print ('Loading Person {}'.format (self.ident) )
        #Just simulating
        self.name = random.choice ( ['Alice', 'Bob', 'Mallroy'] )

@Cached (Cache)
class Animal:
    def load (self):
        print ('Expensive call to DB')
        print ('Loading Animal {}'.format (self.ident) )
        #Just simulating
        self.species = random.choice ( ['Dog', 'Cat', 'Iguana'] )

sys.getsizeof 返回有趣的值。

如何确定所有缓存对象的实际内存使用情况?

最佳答案

getsizeof这是相当棘手的,这是事实的说明:

getsizeof([])       # returns 72   ------------A
getsizeof([1,])     # returns 80   ------------B
getsizeof(1)        # returns 24   ------------C
getsizeof([[1,],])  # returns 80   ------------D
getsizeof([[1,],1]) # returns 88   ------------E

这里有一些值得注意的事情:

  • A:空列表的大小为 72
  • B:包含 1 的列表的大小多了 8 个字节
  • C:1 的大小不是8字节。造成这种奇怪现象的原因是1作为唯一实体单独存在于列表中,因此 C 行返回实体的大小,而 B 返回空列表的大小以及对该实体的引用。
  • D:因此,这是空列表加上对不同列表的引用的大小
  • E:一个空列表加上两个引用 = 88 字节

我在这里想要表达的是 getsizeof 只能帮助您获取事物的大小。您需要获取事物的大小以及这些事物所指代的事物的大小。这听起来像递归。

看看这个食谱,它可能会帮助你:http://code.activestate.com/recipes/546530/

关于python - 缓存和内存使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14658565/

相关文章:

python - 使用 POST 数据向用户确认通用 FormView POST 成功

python - Pandas - 多条件查找速度

python - Django 应用程序不从 AWS 存储桶的媒体文件夹加载图像

c++ - 如何真正删除 vector

linux - 无法在 openvz 容器上找到内存占用

c++ - 为什么 std::move 之后的析构函数调用是必要的?

python - bash 和 python 管道的区别

python - 如果 "a.pyc"文件存在则删除 "a.py"文件

python - python3.2 不能守护线程吗?

python - 如何摆脱多个嵌套的 for 循环?