最近在用selenium对网页上的数据进行爬取时发现,通过pyinstaller打包成的.exe文件运行时速度越来越慢,通过查找任务管理器里的句柄数,发现可能存在内存泄漏的原因,记录一下关于内存泄漏的处理方法和代码优化
1. 内存泄漏
如果您怀疑代码可能存在内存泄漏,可以尝试跟踪内存分配:
这里我用的是tracemalloc模块下get_traced_memory()方法
自定义current,peak = get_traced_memory()
current:存储当前分配的内存大小,表示当前时刻程序分配内存大小
peak:存储了程序运行期间分配内存大小的峰值
· 关于内存泄漏的改进方法:
1. 使用with语句打开文件可以确保文件在操作完成后被正确关闭
2. 重用DateFrame
3. 异常处理:在可能出现异常的地方使用try-except块,确保异常发生时资源被释放
2. 代码优化
处理大量数据时,优化数据结构是提高程序性能的关键。以下是一些常见的数据结构优化方法:
1.使用适当的数据结构:
根据数据的访问模式选择合适的数据结构。例如,如果频繁进行插入和删除操作,可能更适合使用链表而不是数组。
对于需要快速查找、插入和删除操作的场景,哈希表(散列表)是一个很好的选择。
2. 减少数据结构的空间复杂度:
使用紧凑的数据结构,如位字段(bit fields)或压缩数据结构,以减少内存使用。
对于稀疏数据,使用稀疏数组或稀疏矩阵来节省空间。
3. 优化数据访问模式:
尽量减少缓存未命中的次数,例如,通过使用连续的内存块和避免随机访问。
对于频繁访问的数据,考虑使用缓存或缓冲区来提高访问速度。
4. 使用高效的数据结构实现:
使用经过优化的库,如numpy数组代替内置的Python列表,以提高数值计算的效率。
对于特定的应用场景,选择专门为性能设计的数据结构,如优先队列、跳表、平衡二叉搜索树等。
5. 减少数据拷贝和移动:
在处理大数据时,尽量避免不必要的数据拷贝。例如,使用切片而不是复制整个数据集。
使用原地(in-place)算法来减少内存分配和垃圾回收的开销。
6. 使用批处理和延迟处理:
批量处理数据可以减少函数调用的开销和管理数据结构的时间。
延迟处理(如懒惰计算)可以在需要时才处理数据,而不是预先处理所有数据。
7. 优化数据存储和检索:
对于需要频繁读取的数据,考虑使用索引来加快检索速度。
使用数据库或其他数据存储解决方案来优化大规模数据的存储和查询。
8. 并行处理:
使用多线程或多进程来并行处理数据,以利用多核处理器的性能。
使用并行算法和数据结构来提高处理速度,但要小心同步和资源竞争问题。
9. 内存映射文件:
对于非常大的数据集,使用内存映射文件(mmap)可以减少内存使用,并允许操作系统更有效地管理内存。
10. 算法优化:
分析算法的时间复杂度,并尝试使用更高效的算法。例如,使用快速排序而不是冒泡排序。
3. 将Python程序封装成.exe文件后,监控其性能可以通过以下几种方法:
1. 内置性能分析:
在Python代码中使用time模块来记录关键部分的执行时间。
使用cProfile或其他性能分析库来分析代码的运行效率,然后将其集成到你的应用程序中,使其在运行时能够输出性能数据。
2. 外部性能监控工具:
使用系统监控工具,如Windows的任务管理器或Resource Monitor来监控.exe文件的CPU、内存和磁盘使用情况。
使用专门的性能监控软件,如Microsoft Application Verifier、Performance Monitor (PerfMon)、AMD CodeAnalyst或Intel VTune Amplifier,这些工具可以提供更详细的性能数据。
3. 日志记录:
在.exe文件中集成日志记录功能,记录程序的运行状态、资源使用情况和错误信息。这可以通过Python的logging模块实现。
日志可以帮助你分析程序在不同阶段的性能表现,以及在出现问题时提供诊断信息。
4. API监控:
如果.exe文件提供了API接口,可以使用API测试工具来监控其对请求的响应时间和资源消耗。
5. 图形界面性能测试:
如果.exe文件是一个图形界面应用程序,可以使用UI自动化工具,如Selenium或PyAutoGUI,来模拟用户交互并测量响应时间。
6. 第三方库:
使用第三方库,如psutil,来从Python代码中获取系统资源使用情况,并将其记录到日志中或在运行时显示。
7. 分布式跟踪:
如果适用,可以使用分布式跟踪系统,如Zipkin或Jaeger,来监控微服务或分布式应用程序的性能。