内存溢出问题排查

    系统中需要运行一个脚本,脚本中通过项目配置,会调用Django的model,而且脚本中是一个轮询机制,会不断的查库操作,公司内部监控平台爆出服务器内存占用过高,排查到该脚本。

内存无法释放,持续增长

  1. 分析内存工具,tracemalloc 工具包;
import tracemalloc
class Ticker(object):
	def __init__(self):
	def run(self):
		""""逻辑块"""
        a = tracemalloc.take_snapshot()
        e = a.compare_to(c, "lineno")
        for elem in e[0:10]:
                elem = r"{}".format(elem)
                sub = re.search(r".*\\(.*)\\(.*):.*: (size=.*), count.*", elem)
                if sub is None:
                    print(elem)
                elif "tracemalloc.py" == sub.group(2):
                else:
                    print(sub.group(1), sub.group(2), "----", sub.group(3))
        print("++++++++++++++++++++++++++++++++++++++++")
if __name__ == '__main__':
    T = Ticker()
    tracemalloc.start()
    c = tracemalloc.take_snapshot()
    while True:
        asd = r.get("ht_mq_power")
        if asd == "0":
            print("redis  ht mq_power off")
            sys.exit()
        T.run()
        time.sleep(0.3)

2.》》》运行结果

<frozen importlib._bootstrap_external>:487: size=101 KiB (+101 KiB), count=1040 (+1040), average=100 B
redis connection.py ---- size=64.1 KiB (+64.1 KiB)
fields related.py ---- size=21.9 KiB (+21.9 KiB)
utils functional.py ---- size=14.7 KiB (+14.7 KiB)
models options.py ---- size=10.7 KiB (+10.7 KiB)
lib _weakrefset.py ---- size=10104 B (+10104 B)
models expressions.py ---- size=8736 B (+8736 B)
pymqi __init__.py ---- size=8584 B (+8584 B)
lib _weakrefset.py ---- size=8512 B (+8512 B)
++++++++++++++++++++++++++++++++++++++++
<frozen importlib._bootstrap_external>:487: size=101 KiB (+101 KiB), count=1040 (+1040), average=100 B
redis connection.py ---- size=64.1 KiB (+64.1 KiB)
fields related.py ---- size=23.2 KiB (+23.2 KiB)
utils functional.py ---- size=14.7 KiB (+14.7 KiB)
models options.py ---- size=10.7 KiB (+10.7 KiB)
lib _weakrefset.py ---- size=10104 B (+10104 B)
models expressions.py ---- size=8808 B (+8808 B)
pymqi __init__.py ---- size=8584 B (+8584 B)
lib _weakrefset.py ---- size=8512 B (+8512 B)

3.分析
通过运行上面段的代码,会发现不断打印出每一次轮询内存占用详情,
(sub.group(1), sub.group(2), “----”, sub.group(3),
这里的:sub.group(1), sub.group(2) 代表的是哪个文件内存占用问题,
sub.group(3) 代表的是占用大小
分析出来: 1.models expressions.py这个文件占用会随着轮询次数的增长越来越大,联想到是否是Django的惰性加载机制,也就是会将查询SQL进行缓存,
2.fields related.py这个文件内存占用一样越来越大,这个是一个Django外键的文件,是否在逻辑块内有对象循环引用导致,Python的垃圾回收机制无法回收,所以引用gc模块,手动删除创建的每个Django查询对象,并主动进行垃圾回收
4.验证
通过在逻辑块中加入查询执行SQL代码:from django.db import connection import gc """"逻辑代码""" print(connection.queries)
5.结论
事实上打印的SQL一直在递增,都是之前的执行SQL累加在一个list里面

from django import db
def func():
	"""logic code"""
	obj = Model.object.get(id=123)
	del obj
	gc.collect()
	db.reset_queries()  # 清除缓存的执行SQL
                    记一次Django缓存优化过程前言    系统中需要运行一个脚本,脚本中通过项目配置,会调用Django的model,而且脚本中是一个轮询机制,会不断的查库操作,公司内部监控平台爆出服务器内存占用过高,排查到该脚本。问题内存无法释放,持续增长分析内存工具,tracemalloc 工具包;分析过程1.代码import tracemalloc class Ticker(object): 	def __init__(self): 		pass 	def run(self): 		""""逻辑
				
一、django的调试模式 django的调试模式功能强大,但是在该模式下,所有的SQL查询都会被保存在内存中,所以项目上线后应该关闭调试模式,避免内存溢出。如果你发现自己的django项目内存占用不断升高,不用慌,可能仅仅是由于开启了调试模式。 二、werkzeug的调试模式 安全团队的同事提醒我们django项目的调试模式被打开了,找了半天才发现打开的是werkzeug的调试模式而不是d...
项目中用到了数据这块用到了,python 其中就用了Django 搭建了一个管理平台,还有就是一些数据接口。但是运行了一段时间项目老是挂,然后重启后访问一会,又会挂掉。检查日志发现是Cannot allocate memory [core/master_utils.c line 740,无法分配内存。最终发现原来是框架没有关闭调试模式造成的 关闭调试模式,找到项目的settings.py文件
Django的queryset是惰性的,使用filter语句进行查询,实际上并没有运行任何的要真正从数据库获得数据 2 只要你查询的时候才真正的操作数据库。会导致执行查询的操作有:对QuerySet进行遍历queryset,切片,序列化,对 QuerySet 应用 list()、len()方法,还有if语句 3 当第一次进入循环并且对QuerySet进行遍历时,Django从数据库中获取数据,在它...
Django 缓存框架浅析 + 内存分析 动态网站存在一个基本权衡是——它们是动态的。每次用户请求一个页面,web 服务器需要提供各种各样的计算——从数据库查询到模板渲染再到业务逻辑——最后生成页面呈现给用户。从处理开销的角度来看,这比读取文件的开销要高得多。 缓存是将一些需要经过大量计算的结果存储在一个指定区域中,避免再次访问时的重复计算(处理好缓存的失效时机,否则会破坏数据的实时性)。通俗的讲,缓存就是用空间换取时间的一种策略方案。 使用缓存(这里主要指后端缓存)有以下主要优势: 提升接口响应速度
最近用django+apache+mod_python搭建的一在线元器件交易平台网站([url]http://www.ecgoo.net/[/url]),由于网络爬虫的频繁光顾,导致经常有httpd进程狂吃内存,网站无法访问。 google了一下,发现有篇英文文档很有帮助,因此翻译了下,希望对他人有帮助 原文:[url]http://blog.webfaction.com/tips-t...
一、python有自动垃圾回收机制(当对象的引用计数为零时解释器会自动释放内存),出现内存泄露的场景一般是扩展库内存泄露或者循环引用(还有一种是全局容器里的对象没有删除) 前者无需讨论,后者举例如下(Obj('B')和Obj('C')的内存没有回收)(貌似循环引用的内存Python解释器也会自己回收(标-清除垃圾收集机制),只是时间早晚的问题,也就是说我们在编码中不需要耗费精力去刻意避免
django下使用celery作为异步任务系统,十分方便。 同时celery也提供定时任务机制,celery beat。使用celery beat 可以为我们提供 cron,schedule 形式的定时任务。 在django下使用celery beat的过程中,发现了 celery beat进程 占用内存非常大,而且一直不释放。 怀疑其有内存占用不释放的可能。 因为之前使用dja
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': '127.0.0.1:11211', ```python CACHES = { 'default': { 'BACKEND': 'django_redis.cache.RedisCache', 'LOCATION': 'redis://127.0.0.1:6379/', 'OPTIONS': { 'CLIENT_CLASS': 'django_redis.client.DefaultClient', 3. 在 views.py 文件中,使用缓存装饰器来缓存数据: ```python from django.core.cache import cache @cache.page('my_key', 60*60*24) # 保存一天 def my_view(request): # 加载数据的代码 4. 在模板中使用 cache 标签缓存模板: ```django {% load cache %} {% cache 60*60*24 "my_template" %} <!-- 模板代码 --> {% endcache %} 这样,用户在访问页面时,数据只会被加载一次,并且在缓存过期前都会被保存在缓存中。
docker拉取镜像报错 error pulling image configuration: download failed after attempts=6: dial tc 10471
docker拉取镜像报错 error pulling image configuration: download failed after attempts=6: dial tc 迎风搬石头: 完美解决docker pull镜像问题 docker拉取镜像报错 error pulling image configuration: download failed after attempts=6: dial tc Django 聚合函数使用 docker拉取镜像报错 error pulling image configuration: download failed after attempts=6: dial tc Django 聚合函数使用