基于 AI 代码助手 DeepSeek R1 分析 OOM 问题

文章摘要
腾讯云 AI 代码助手的 DeepSeek R1 模型上线后,我们收到了许多开发者的使用分享,在此分享一篇腾讯资深程序员(文章下文以“我”代称)的使用分享文章,感兴趣的伙伴们欢迎一起来体验腾讯云 AI 代码助手的 DeepSeek R1 模型。

一、问题背景
AI 技术如火如荼, DeepSeek 更是震惊全球。我是腾讯云 AI 代码助手插件最早的用户之一,一直在使用 AI 技术提升编码效率,从开始的不断吐槽,到如今的爱不释手,切实的感受到 AI 技术对于编码效率的提升和自身成长的协助。代码补全,智能提示和代码自动生成,AI 工具确实全方位的给予我们 RD 切实的帮助。
尤其是 DeepSeek R1 深度思考模型引入以后, AI 在解决一些深层次问题上,也体现了巨大的价值和参考性。
本文以实际中遇到的一个内存 OOM 问题为切入点,结合 DeepSeek R1 的提示和帮助,不断探究 AI 工具的能力边界,有了一些一线的经验和教训。在这里把为分析的过程记录下来,为自己一些总结和沉淀,也为他人一些参考和激励。
几点说明:
1) 这里分析的是 C++ 的代码问题,主要是 C++ 的 vector 的内存管理策略的代码
2) 这里使用的是腾讯云 AI 代码助手自带的满血的 DeepSeek R1 版本,而不是 DeepSeek 官网的版本,主要是因为 DeepSeek 官网太忙了
我的总体结论是:
在使用 DeepSeek R1 进行复杂问题分析时, DeepSeek R1 展现出独特的智能辅助价值。系统能够快速生成结构化框架,提供基础的逻辑链条和关键的概念解析,在问题拆解和知识关联方面表现出很明显的优势。特别是在问题初步探索阶段,其多角度发散的思维提示有效拓展了 RD 的思考边界和视角范畴。但在处理需要深度专业推演的复杂场景时,系统输出的全面性和纵深性会出现衰减,存在局部逻辑断层或事实性偏差的风险。
二、内存 OOM
从事后的问题分析看,服务出现 OOM 的原因是明确的,下面是这个问题的分析过程:
1) 服务是支持数据双版本+数据热加载的,也就是说服务有两个版本的数据,并且在数据更新的时候,对外并不停服
2) 单个版本的数据量并不小,大约是 17G 左右的内存占用量;两个相邻版本的内存差异不大,所以双版本大约是占用 34G 左右的内存空间
3) 为了避免内存加载时候的大起大落,服务采用了内存复用+循环替换的策略更新数据
a) 服务大部分情况下有两个版本的数据,标记为 cur+pre,cur 使用当前的版本,pre 是前一个数据版本
b) 当服务收到数据更新的命令后,标志 pre 不可使用,这个时候只有 cur 对外提供服务, pre 用于更新数据
c) 复用 pre 的内存空间加载新数据
d) 数据加载成功以后,使用原子交换的方式,交换 pre 和 cur ,保持 cur 和 pre 版本的的逻辑相关性( pre 是前一个版本, cur 是的当前的最新版本)
e) cur 和 pre 同时对外提供服务,直到启动下一次数据更新的流程
4) 进行了一次数据热加载以后,看起来好像是内存没有释放,导致了 34+17=51G 的内存占用,第二次数据热加载以后,内存 68G 超过 64G 的限制,直接 OOM
所以问题的焦点就是:为什么基于内存复用的数据热加载,会导致内存占用量翻倍?
三、问题分析
偷天换日-技术问题模拟
业务背景牵扯的技术细节比较多。
抛开这些业务细节,使用一段简单的代码模拟同样的技术问题,然后让腾讯云 AI 代码助手 DeepSeek 回答,更容易定位问题的根因。
这里相当于做了一个技术问题的 transform ,来一个偷天换日。
简单的描述一下问题:
1) 问题聚焦到 std::vector 对象的内存管理上
2) std::vector 对象的内存大小是 capacity 决定的,而不是 size
3) 当 std::vector 对象动态增加对象的时候,其内存是如何管理的?当内存比较大的时候,内存管理策略会不会有调整和优化?
代码如下:
这里使用 1G=1024*1024*1024 来模拟 vector 内存比较大的情况,使用 delta=1 来模拟一个较小的内存增量。对应的问题是:这段代码的输出结果是什么?
1、小试牛刀-vector 对象如何管理内存
输入给腾讯云 AI 代码助手 DeepSeek 的问题是:"在主流标准的编译器上,以上代码的输出会是什么?"。
剔除思考过程,腾讯云 AI 代码助手 DeepSeek 的回答截图如下:

这个回答是相当厉害了:
1) 首先在 GCC 上的结果是正确的,因为我可以立马验证一下,所以推断在其他编译器上的结果也是 OK 的
2) 非常清晰的解释了 vector 对象的内存管理策略,包括初始化和动态扩容不同时机的内存管理策略
3) 还非常细心的给出了大内存管理可能的风险,以及附加的小内存测试建议
为了确认正确性,我到网上 GCC 自带 vector 的实现确认了一下:
GCC vector 内存扩容策略 网址链接:

不同版本的实现,这个内存管理策略是基本一样的。
有了这个结论,就可以明确 OOM 的原因了:
1) 导航数据热更新的时候,相邻版本之间数据差距较小
2) 具体到某个版本上,根据实际的统计,差不多增加万分之五之内的规模
3) 如果是 17G 的内存占用量,数据更新后,实际也就需要 17G +万分之五的增量
4) vector 第一次数据热加载,capacity==size,17G 左右
5) vector 内存复用的第二次数据热加载,实际需要的内存量稍有增加,但是根据 vector 的内存增量策略,实际会导致 17*2=34G 的内存占用量
6) 所以两次数据热更新之后, OOM 发生了。
但是问题还得继续分析:在当前的内存管理策略下,如何避免大内存导致的内存 OOM ?
2、顺藤摸瓜-确保 capacity 和 size 相差不大
抛给 DeepSeek 的问题,还需要斟酌一下,我最终是这样提问的:"当内存比较大的时候,如何保证 vector 对象的 capacity 和 size 的差距维持在一个较小的范围之内?"
腾讯云 AI 代码助手 DeepSeek 的回答截图:


3、这个答案也非常惊艳,有 3 个点给我印象非常深刻:
1) 通过 reserve 然后 resize 的调用,确保 capacity==size
2) 通过 swap 技巧或者 C++11 支持的 shrink_to_fit 的调用,剔除 vector 不必要的内存,然后保证 capacity==size
3) 建议采用分阶段预留策略
这个答案已经非常接近我自己的理想结果了,但是仍然有问题:
1) 在 reserve 扩大内存的执行过程中,会保留老的内存内容,然后把老的内容 copy 到新分配的空间中去
2) 这样在某个瞬间(持续时间不会太长),会有两份大内存,从而有 OOM 的风险。
3) 当然,上面的提问并没有把老内存不需要这个条件告诉 DeepSeek,所以还需要进一步提问。
4、步步为营-剔除老内容的维护诉求
腾讯云 AI 代码助手 DeepSeek 非常像一个技术大咖了,给他的问题要非常明确才好。到了这个阶段,我的问题是:" vector 对象的老内容是不需要维护的,通过 resize 动态调整内存大小,当内存比较大的时候,如何保证 vector 对象的 capacity 和 size 相等的,并且过程中不会产生两份比较大的内存占用?"
腾讯云 AI 代码助手 DeepSeek 的回答截图:


腾讯云 AI 代码助手 DeepSeek 的答案非常简单直接:直接把老的对象释放掉,其占用的大块内存也释放了,然后重新申请大块的内存。在这个过程中,不会有两份的大块内存占用了。
这个方案我曾经放到线上。
但是大块内存的回收,在 TCMalloc 的实现中,可能会导致全局内存锁的使用,从而影响服务的稳定性,导致部分请求在一个极小的时间范围内(可能是在毫秒之内)请求失败。所以我希望避免大块内存的释放然后再重新申请的操作。
5、抽丝剥茧-避免大块内存的频繁操作
我的问题是这样的:"上面的方案,不会有大内存两份占用的问题了,但是会出现大块内存的释放和重新申请的问题,这在一定程度上会影响服务的稳定性。是否可以通过分阶段内存预留技术,避免大块内存的释放和重新申请问题?"
腾讯云 AI 代码助手 DeepSeek 的回答截图:


这个已经非常接近我的最终答案了,但还是有些差异。
这些差异可能是我的问题本身引起的;但是问题分析到了这里,我觉得最好是反客为主了,比如我给出答案,让腾讯云 AI 代码助手 DeepSeek 评价这个方案的优劣。
6、反客为主-你认为我给出的方案 OK 吗
我给出一段代码,然后给出我的目标,最后询问腾讯云 AI 代码助手 DeepSeek 这个目标是否达成了。
以下是代码:
我自己的评估是这样的:
1) 通过预留 10% 的空间,避免大块内存的释放和重新申请
2) 通过 clear,避免老内存的 copy ,从而避免瞬间的内存 double
3) 通过 reserve 和 resize 联合调用,确保 capacity 和 size 相差不大
我的问题是这样的:" resizeVec 这段代码,对于些许的内存增量,比如内存增加千分之一,可以避免 vector 大块内存的释放和重新申请,从而维护服务的稳定性。这个说法是正确的吗?"
DeepSeek 的回答截图:


这个回答我有一点点失望:
1) 原代码扩容了 10% 的内存余量,存在一定的空间浪费。DeepSeek 抓住这一点不放,给出了它认为的更好方案,感觉缺乏一些整体架构和全局考量的视野
2) 其实我更加期望 DeepSeek 给出这样的答案:10%的内存余量有写死代码的问题,不够灵活,可以修改为配置参数。
3) 修正后的代码,没有了 clear 的调用,这可能会导致瞬间的内存 double ;当内存比较大的时候,有 OOM 的风险。
4) 我的代码中已经明确给出了 clear 函数的调用,但是 DeepSeek 建议的答案中没有注意到这一点。
四、使用总结
腾讯云 AI 代码助手 DeepSeek R1 的能力确实非常强大! 体现在几个方面:
1) 博。 比如我说到主流的 C++ 编译器,它会聚焦在 GCC/Clang/MSVC 等上面,都给出了明确而清晰的回答。DeepSeek R1 在这里就像是一个技术的百科全书,全面的技术大咖,让我们普通 RD 有了一些上帝视野,真的是如虎添翼的感觉。
在极限编程的实践中,非常推崇结对编程,意思是两个人一起编程,相互监督,相互促进,实现高质量的代码编程。但是在实际当中这很难落实,在某种程度上成为了编程的乌托邦。有了 DeepSeek R1 之后,我感觉这个理念可以实现了。腾讯云 AI 代码助手 DeepSeek R1 就像是一个满腹经纶的技术大咖,可以免费的给出非常专业和精准的技术回答,真的是 RD 的好帮手。
2) 专。 腾讯云 AI 代码助手 DeepSeek R1 的回答非常的专业,比如它可以区分不同编译器和标准的不同实现,例如上面关于 vector 的 swap 技术和 shrink_to_fit 的函数调用,这是非常专业的 C++ 知识范畴了,真的是让人印象深刻。
3) 准。 腾讯云 AI 代码助手 DeepSeek R1 非常的准确,对于代码而言,它不仅是给出语言描述,而且有几乎可以立马使用的代码实现,非常精准的命中了需求的靶点。
当然,如果非要吹毛求疵,我们也可以说腾讯云 AI 代码助手 DeepSeek R1 还存在一些缺乏全局视野和纵深思考的不足。但是也必须认识到,至少有部分原因,是我们缺乏足够精确的语言描述这些所谓的全局视野和纵深考点,导致腾讯云 AI 代码助手 DeepSeek R1 无法有效地把这些因素融入到思考问题的背景中去。
腾讯云 AI 代码助手 DeepSeek 还在不断地演进,我们自己更需要不断地学习。感谢腾讯云 AI 代码助手,让我有更高效的编程体验,也期待它的不断升级。
五、快来开启代码智能化吧
看了那么久,心动不如行动~快来实操体验吧!
操作:操作插件更新操作指引
步骤 1: 安装开发工具 IDE (如已装请忽略)
Visual Studio Code IDE 下载指南:
Jetbrains IDEs 下载指南:
https://www.jetbrains.com/ides
步骤 2: 安装腾讯云 AI 代码助手(如已装请忽略)
在 Visual Studio Code 或 Jetbranis IDEs(如 IntelliJ IDEA、Goland、PyCharm、Rider 等) 插件市场, 搜索「腾讯云 AI 代码助手」,秒安装。

在 Visual Studio Code 中安装指南:
https://copilot.tencent.com/setup/vscode
在 Jetbrains IDEs 中安装指南:
https://copilot.tencent.com/setup/intellij
步骤 3: 登录腾讯云 AI 代码助手,可用微信扫码或手机号快速登录

步骤 4: 更新插件方式
VS Code 更新方式

Jetbranis IDEs 更新方式(如 IntelliJ IDEA、Goland、PyCharm、Rider 等) Jetbrains 系列

评论