当前位置: 首页 > 面试题库 >

'safe'json_decode(,,,)以防止耗尽内存

督嘉言
2023-03-14
问题内容

在我的应用中,我经常调用一个返回json字符串的外部api。

$url = 'api.example.com/xyz';
$blah = json_decode( file_get_contents( $url ) );

但是在某些情况下

PHP致命错误:内存中已耗尽xxx字节(尝试分配32字节)的内存大小…

我无法控制外部API,当然可以增加php的内存,但这有一些缺点。

1-无论我设置的大小,仍然可能太小。2-如果将内存大小设置为“ infinite”(无限),则可能会导致服务器被杀。

理想情况下,我想在调用json_decode(…)之前先“检查”字符串是否导致内存耗尽。

那可能吗?


问题答案:

如果它们设法耗尽服务器的内存,则必须获得大量的JSON响应。以下是一些指标,这些指标包含一个包含多维关联数组的1
MB文件(包含准备输入到具有不同数据类型的三个MySQL表中的数据)。

当我include和文件作为数组加载到内存中时,我的内存使用量达到9
MB。如果我使用来获取原始数据file_get_contents(),则它需要1
MB的内存。然后,PHP数组strlen()与数据的比率大约为1:9 (最初以输出var_export())。

当我运行时json_encode(),峰值内存使用不会增加。(PHP在块中分配内存,因此通常会产生一些开销,在这种情况下,足够包含JSON的字符串数据;但是它可能会使您增加一个块。)作为字符串的结果JSON数据需要670
KB。

当我将JSON数据加载file_get_contents到字符串中时,它需要0.75
MB的内存。当我json_decode()在其上运行时,它需要7 MB的内存。然后,对于RAM需求,我将解码的 JSON数据字节大小
本机PHP数组或对象 的最小比率为1:10 。

要在解码之前对JSON数据进行测试,您可以执行以下操作:

if (strlen($my_json) * 10 > ($my_mb_memory * 1024 * 1024)) {
    die ('Decoding this would exhaust the server memory. Sorry!');
}

…其中$my_json是原始JSON响应,$my_mb_memory是分配的RAM,已转换为字节以与传入数据进行比较。(当然,您也可以使用intval(ini_get('memory_limit'))整数来获取内存限制。)

如下所述,RAM的使用也将取决于您的数据结构。相比之下,还有一些快速测试用例,因为我很好奇自己:

    1. 如果我创建一个整数为1-60000的一维数组,则保存的PHP数组大小为1 MB,但是RAM的峰值使用量在10.5和12.5 MB之间(好奇振荡),或比例为1:12-ish。
    1. 如果我将一个1 MB文件的值的数据作为12000个随机字符串作为基本关联数组创建,则加载时的内存使用量仅为5 MB。比例为1:5。
    1. 如果我创建一个价值1 MB的文件作为相似的关联数组,其中一半条目是带有数字索引的字符串数组,则内存使用率为7 MB,比例为1:7。

因此,您的实际RAM里程可能会相差很大。
还应注意,如果您绕一圈传递大量数据并进行一些操作,那么您的内存使用量可能会比json_decode()单独导致的使用量高很多(或成倍地增加,具体取决于您的代码经济性)。

调试内存使用情况,您可以在代码中使用memory_get_usage()和/或memory_get_peak_usage()间隔很长时间来记录或输出代码不同部分中使用的内存。



 类似资料:
  • 然而,我遇到了一些问题。特别是带有内部异常的WebException(“无法连接到远程服务器”): 无法对套接字执行操作,因为系统缺少足够的缓冲区空间或队列已满127.0.0.1:52395 我正在尝试以每线程500次迭代的方式运行100个线程。 我可以使用更少的迭代和/或更少的线程来操作测试,因为看起来套接字最终会退出这个TIME_WAIT状态。但是,这不是一个解决方案,因为它没有充分测试web

  • 我目前在Azure中托管了几十个网站,最近开始在每个web应用的门户刀片中看到“内存资源耗尽”警告: 我在两个S3标准(大型)应用程序服务计划中托管我的网站,我在所有网站上都会收到警告,无论它们在哪个应用程序服务计划上。 有趣的是,当查看任一应用服务计划的内存使用率时,我总是低于40%,内存使用率实际上相当一致。我从未看到峰值或任何接近85%内存使用率的东西。 我的问题是,我是否误解了警告消息?是

  • 我编写的java应用程序遇到了一个问题,导致硬件性能问题。问题(我很确定)是,我运行应用程序的一些机器只有1GB的内存。当我启动java应用程序时,我将堆大小设置为-xms512m-xmx1024m。 我的第一个问题是,我的假设是否正确,因为我将机器的所有内存分配给java堆,这显然会导致性能问题?

  • 我试图理解为什么下面的Java程序给出了< code>OutOfMemoryError,而对应的程序却没有< code >。parallel()没有。 我有两个问题: > 该程序的预期输出是什么? 不带<代码>。parallel()看起来这只是输出< code>sum(1 2 3...)这意味着它只是“停留”在平面图中的第一个流,这是有意义的。 对于并行,我不知道是否有预期的行为,但我的猜测是它以

  • 是否还有其他地方对进程或用户可用的最大内存设置了限制?我开始没有选择了。

  • 问题内容: 致命错误:在第269行的D:\ xampplite \ htdocs \ Scraper \ PHPExcel \ Reader \ Excel2007.php中,耗尽了134217728字节的内存大小(尝试分配1078799字节) 即使我仅尝试使用PHPExcel打开〜350 KB的小型excel文件,我的128M PHP内存限制也很快耗尽了。 虽然,我可以增加配置中的内存限制,但是