You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用LWP::UserAgent大文件PUT时的内存占用异常问题

解决LWP及S3相关模块传输大文件时内存暴涨崩溃的问题

问题现象

  • 使用LWP::UserAgent或依赖LWP的S3客户端(Paws::S3、Net::Amazon::S3::Client、Amazon::S3)传输大文件时,进程内存占用会暴涨至40GB以上,最终触发段错误崩溃。
  • 单独分段读取待传输文件时,内存占用稳定在1.4GB以内,无异常;但加入LWP相关传输逻辑后内存显著上升,传输至55%时崩溃。
  • S3类模块故障出现更早,内存随文件块传输逐步攀升,直至达到40GB阈值。

核心原因

LWP默认会将请求体全部加载到内存中缓存,即使你分段读取文件,只要以字符串形式传递内容给LWP,就会导致内存持续堆积。S3相关模块基于LWP实现时,若未启用流式上传,同样会把每个文件块的内容驻留在内存中,最终引发内存溢出。

解决方案

针对LWP::UserAgent的流式上传实现

直接绑定文件句柄作为请求内容,让LWP逐块读取并发送数据,避免加载整个文件到内存:

use LWP::UserAgent;

my $ua = LWP::UserAgent->new;
open my $fh, '<:raw', '/path/to/large_file' or die $!;

my $response = $ua->post(
    'http://your-server/upload-endpoint',
    Content => $fh,  # 直接传递文件句柄实现流式发送
    'Content-Length' => -s '/path/to/large_file',  # 必须指定文件总大小
);

close $fh;

如果是分块上传,每块处理完毕后立即关闭对应句柄,避免句柄和内存堆积。

针对S3客户端模块的流式配置

所有依赖LWP的S3模块,需强制启用流式上传,避免块内容驻留内存:

  1. Paws::S3
use Paws;

my $s3 = Paws->service('S3', region => 'your-region');
open my $fh, '<:raw', '/path/to/large_file' or die $!;

$s3->PutObject(
    Bucket => 'your-bucket',
    Key => 'large_file_key',
    Body => $fh,  # 传递文件句柄而非内容字符串
    ContentLength => -s '/path/to/large_file'
);

close $fh;

分块上传时,每个UploadPart需传递对应块的文件句柄(提前定位到块起始位置),上传完成后立即关闭句柄。

  1. Net::Amazon::S3::Client
use Net::Amazon::S3;
use Net::Amazon::S3::Client;

my $s3 = Net::Amazon::S3->new(
    aws_access_key_id => 'your-key',
    aws_secret_access_key => 'your-secret',
);
my $client = Net::Amazon::S3::Client->new(s3 => $s3);
my $bucket = $client->bucket(name => 'your-bucket');

open my $fh, '<:raw', '/path/to/large_file' or die $!;
$bucket->add_key(
    'large_file_key',
    $fh,  # 流式传递文件句柄
    { content_length => -s '/path/to/large_file' }
);

close $fh;

额外检查点

  • 避免在代码中重复赋值文件内容到变量,及时释放无用变量。
  • 确认分块上传逻辑中,每个块的内容仅被读取一次,未被意外缓存。

内容的提问来源于stack exchange,提问作者Timothy R. Butler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 04:40:18