解决PHP处理图片时内存占用过高问题
用过GD库的同学可能都知道,使用imagecreatetruecolor()函数创建一个真彩色的画布是第一步。但是,如果画布的宽高超过平常的宽高,会带来极大的内存消耗。比如,一个9600×4800的画布,会带来190M的内存消耗。这时,如果服务器的free空间过小,就会导致内存耗尽,出现各种报错。本文旨在提供优化服务器时对大图片的处理方法。
首先,说下业务场景。我要对用户上传的图片进行裁剪,变成我想要的宽高比。注意,是2:1这种宽高比。 因为用的服务器内存总共只有512M,处理小图片时还好,但是一旦接触到4M以上的图片文件,内存耗尽就成了一个block的点。它会引发nginx报502的错误,因为nginx无法从php-fpm那里获取到相应的值。报错日志:a client request body is buffered to a temporary file。3119133 recv() failed (104: Connection reset by peer) while reading response header from upstream 这里可以提供下,我使用GD库对图片进行处理时的内存占用情况的日志:
获取大小内存-1 376.12 kb
获取大小内存 4.98 mb
#这里使用了imagecreatetruecolor
获取大小内存2 192.53 mb 图片width:9600height4800
获取大小内存3 287.92 mb
获取大小内存4 287.92 mb
获取大小内存5 287.92 mb
获取大小内存6 100.38 mb
获取大小内存7 104.48 mb
#这里实行了最后一步,释放内存 获取大小内存+1 376.21 kb
可以看到,很明显的内存占用,关于图片宽高对内存的影响,网上有个公式:
(width*height)* 3 * 图片位数 //乘以3是因为创建的是rgb色彩模式的图像,有3个通道
可以看到,这仅仅是一个4M的图片,就对服务器提出了将近200M的消耗。当然这里不能仅仅用大小size来衡量,还要加入Width和Height来度量实际的大小。这也是我们处理图片上传时,为什么不仅要加入大小的限制 ,还要加入宽高的限制的原因所在。 我的解决方法是使用了一个第三方软件:imagemagick。 这里我要强推下这个软件,他可以把你的多张图片合成一个pdf,也可以将一个pdf转换成多张图片,而且可以对图片增加诸如炭笔,油画等特效。
#CentOs安装方法 yum install ImageMagick #测试安装成功 convert -v
因为是我个人使用,所以直接在upload的时候实时执行了以下命令。
$command = "convert -resize *x* 'images/a.jpg' 'images/a.jpg'"; $result = exec($command, $res, $code); #这里直接使用php的exec命令即可。对参数进行下简单说明。 #convert imagemagick的转换命令 #-resize 要执行的命令 #*x* 宽乘以高,这个是小写的x #*.jpg 原图位置 #*.jpg 转换后图片的名称,不改则默认覆盖原图
加上之后,内存的占用日志
获取大小内存-1 384.83 kb 获取大小内存 384.97 kb 获取大小内存+1 385.17 kb 执行命令convert -resize 3696x1848! images/20190213094940_940.jpg images/20190213094940_940.jpg #这里在高这里加上!是表示不接受imagemagick默认的等比缩放,强制转换成这个大小
可以看到,处理速度和内存占用都降了下来,这一步,将内存的压力转换成了Cpu的压力。
解决PHP处理图片时内存占用过高问题的更多相关文章
- 通过修改my.ini配置文件来解决MySQL 5.6 内存占用过高的问题
打开后台进程发现mysql占用的内存达到400+M. 修改一下my.ini这个配置文件的配置选项是可以限制MySQL5.6内存占用过高这一问题的,具体修改选项如下: performance_schem ...
- CLR Profile解决内存占用过高
CLR Profile解决内存占用过高的问题 炮哥:"嘿,哥们,忙啥呢,电脑卡成这逼样." 勇哥:"在用CLR Profile工具分析下FlexiPrint的内存占用情况 ...
- Firefox内存占用过高解决方法
刚开始使用firefox火狐浏览器的时候,你会发现firefox占用内存大,CPU占用率高,打开网页停顿等问题,其实这些是因为firefox没有进行优化,默认设置是标准的设置的原因,解决方法如下: 一 ...
- [转帖]Linux中buff/cache内存占用过高解决办法
Linux中buff/cache内存占用过高解决办法 https://www.cnblogs.com/rocky-AGE-24/p/7629500.html /proc/sys/vm/drop_cac ...
- Spring cloud开发内存占用过高解决方法
https://blog.csdn.net/wanhuiguizong/article/details/79289986 版权声明:本文为博主原创文章,转载请声明文章来源和原文链接. https:// ...
- [2017-08-09]一则使用WinDbg工具调试iis进程调查内存占用过高的案例
最近遇到一个奇葩内存问题,跟了三四天,把Windbg玩熟了,所以打算分享下. 症状简介 我们团队的DEV开发环境只有一台4核16G的win2012r2. 这台服务器上装了SqlServer.TFS(项 ...
- 【转】一则使用WinDbg工具调试iis进程调查内存占用过高的案例
最近遇到一个奇葩内存问题,跟了三四天,把Windbg玩熟了,所以打算分享下. 症状简介 我们团队的DEV开发环境只有一台4核16G的win2012r2.这台服务器上装了SqlServer.TFS(项目 ...
- 一个神奇的bug:OOM?优雅终止线程?系统内存占用较高?
摘要:该项目是DAYU平台的数据开发(DLF),数据开发中一个重要的功能就是ETL(数据清洗).ETL由源端到目的端,中间的业务逻辑一般由用户自己编写的SQL模板实现,velocity是其中涉及的一种 ...
- Linux 内存 占用较高问题排查
Linux 内存 占用较高问题排查 niuhao307523005 2019-04-24 14:31:55 11087 收藏 11展开一 查看内存情况#按 k 查看 free #按兆M查看 free ...
随机推荐
- 【ARM-Linux开发】ARM嵌入式设备Linux系统启动步骤和方式
1). 简介 本文简单介绍ARM嵌入式设备基于嵌入式Linux操作系统时候的启动步骤和启动方式, 区别与X86平台,ARM平台下并没有一个标准的启动步骤,不同ARM SoC都会使用各自定义的boot ...
- LVDS接口液晶屏点屏流程
使用MStar的TSUM系列的芯片,主要是用来驱动LVDS的屏.在硬件设置无误的情况下(屏开关口.屏电压.PWM等),按照屏规格书上的参数配置屏参,就可以完成点屏了.大概分为几个步骤,确定屏供电电压, ...
- php判断key是否存在的两种方法
array_key_exists($key, $array) isset($array[$key]) 两种方式都可以!
- windows系统转linux系统后磁盘的处理
背景: 原服务器是windows操作系统的.在没有进行格式化的情况下,重新安装了linux系统.比如centos7后,磁盘该怎么格式化?以下是演示过程. 1. 查看磁盘情况: # fdisk -l 2 ...
- C++四大特性之封装
C++四大特性 C++作为面向对象编程语言,具备面向对象编程(Object Oriented Programming,OOP,面向对象程序设计)的四大特性.抽象,封装,继承,多态. 所谓抽象,就是对具 ...
- C++用new与不用new创建对象的区别
C++创建对象 一.Alignment问题 重新发现这个问题是因为在体系结构课上提到的一个概念,alignment对齐的概念. class MyClass { public : char c; // ...
- Delphi RSA加解密【 (RSA公钥加密,私钥解密)、(RSA私钥加密,公钥解密)、MD5加密、SHA加密】
作者QQ:(648437169) 点击下载➨delphi RSA加解密 [Delphi RSA加解密]支持 (RSA公钥加密,私钥解密).(RSA私钥加密,公钥解密).MD5加密.SHA1加密.SHA ...
- C语言return返回值深入理解
C语言使用return关键字返回函数值,可以很好对函数做封装,此处的疑问是:函数内部创建的变量都是局部变量,即私有的,作用域就在函数之内,为什么却可以把值传给调用函数? 解释这个问题还需要从C语言调用 ...
- Rust 智能指针(二)
1. Rc<T> 引用计数指针 Rc<T> 是引用计数指针,可以使用clone使得指针所指向的数据具有多个所有者. enum List { Cons(i32, Rc<Li ...
- vue中引入百度地图
xxx.vue <template> <div> <el-input v-model="inputaddr"> </el-input> ...