댓글 검색 목록

[php] PHP 메모리 관리 팁

페이지 정보

작성자 운영자 작성일 20-04-19 19:45 조회 1,119 댓글 0

메모리 문제? 


PHP 메모리 관리에 대한 튜토리얼과 팁에 오신 것을 환영합니다. 배고픈 PHP 스크립트에서 메모리가 부족합니까? 글쎄, 요즘 메모리는 싸고, "더 많은 메모리를 사고, PHP에 더 많은 것을 할당"하는 쉬운 방법으로 가고 싶어합니다.


그러나 사용량이 많은 시스템의 경우 몇 가지 간단한 변경 사항과 닌자 코딩 기술만으로도 성능을 향상 시킬 수 있습니다. 시스템 리소스를 더 적게 사용하고 불필요한 하드웨어를 더 많이 구입할 필요가 없습니다.


PHP에서 메모리 사용량을 어떻게 측정합니까? 성능 향상에 도움이 되는 몇 가지 사용자 기술은 무엇입니까? 알아 보려면 계속 읽으십시오!


ⓘ이 튜토리얼을 시작할 때 모든 예제 소스 코드가 포함 된 zip 파일을 포함 시켰으므로 모든 내용을 복사하여 붙여 넣을 필요가 없습니다.


예제 코드 다운로드 


먼저 약속 된 모든 예제에 대한 다운로드 링크가 있습니다.


소스 코드 다운로드 


소스 코드를 다운로드하려면 여기를 클릭하십시오. MIT 라이센스에 따라 릴리스되었으므로 그 위에 빌드하거나 자신의 프로젝트에서 자유롭게 사용하십시오.


빠른 시작 


  • 폴더에 다운로드하여 압축을 풉니 다.
  • 관련된 데이터베이스가 없으므로 포함 된 각 파일을 따라 가십시오.

메모리 사용량 추적 


이 가이드의 첫 번째 섹션에서는 PHP에서 메모리 사용을 추적하는 방법을 안내합니다. 성능을 최적화 하려는 첫 번째 단계는 성능을 모니터링 하는 것입니다.


메모리 사용량 확인 


고맙게도 PHP에는 현재 메모리 사용량을 보여주는 기본 기능이 제공되므로 추가 도구가 필요하지 않습니다. 우리가 해야 할 일은 memory_get_usage ()를 사용하여 현재 메모리 사용량을 표시하는 것 뿐이며 실제 매개 변수를 전달하여 PHP에 할당 된 총 시스템 메모리를 얻을 수도 있습니다.


<?php echo "TOTAL SYSTEM ALLOCATED MEMORY - " . memory_get_usage(true) . "<br>"; echo "SCRIPT USAGE - " . memory_get_usage(). "<br>"; $foo = []; for ($i=0; $i<10; $i++) { $foo[$i] = "Hello " . $i; } echo memory_get_usage() . "<br>"; unset($foo); echo memory_get_usage() . "<br>"; ?> 


피크 메모리 사용량 


그러나 물론 스크립트의 어느 곳에 나“메모리 검사 점”을 추가하는 것은 멍청 할 것입니다. 따라서 고맙게도, 최대 메모리 사용량을 알려주는 memory_get_peak_usage() 함수가 있습니다.


<?php echo "TOTAL SYSTEM ALLOCATED MEMORY - " . memory_get_usage(true) . "<br>"; echo "SCRIPT USAGE NOW - " . memory_get_usage(). "<br>"; $foo = []; for ($i=0; $i<10; $i++) { $foo[$i] = "Hello " . $i; } unset($foo); echo "PEAK USAGE - " . memory_get_peak_usage() . "<br>"; ?> 


메모리 사용량 프로파일 링 


스크립트의 특정 지점에서 메모리 사용에 대한보다 자세한 정보를 얻으려면 자체 모니터링 스크립트를 작성하거나 도구를 사용해야 합니다. Xdebug는 메모리 프로파일 링을 수행 할 수 있는 도구입니다.


메모리 사용량 제한 


메모리 사용 추적의 첫 번째 닌자 이동을 마스터 했으므로 다음으로 PHP 스크립트의 메모리 제한을 제한 (또는 높이기)으로 넘어갑니다.


PHP 설정 파일 


"메모리 부족"문제가 발생하면 가장 늦게 수정하는 방법은 php.ini 구성 파일에 설정된 메모리 제한을 높이는 것입니다.


memory_limit=256M 


참고 : 그러나 php.ini 파일을 변경하면 전체 서버에 영향을 미칩니다. 여러 스크립트가 엉망이 되어 서버 충돌이 발생할 경우 잠재적으로 치명적일 수 있습니다. 따라서 php.ini에서 제한을 변경하려면 서버가 로드를 처리 할 수 ​​있는지 확인한 후에 만 ​​드물게 변경하십시오.


인라인 설정 제한 


이것은 대신 권장하는 대안입니다.


<?php ini_set('memory_limit', '256M'); ?> 


이런 식으로 메모리 제한은 이 특정 스크립트에 대해서만 발생합니다.


올리거나 올리지 않겠습니까? 


보고서를 작성하거나 대량의 메모리를 필요로 하는 트랜잭션을 수행해야 한다면, 그렇게 하십시오… 그러나 이러한 작업을 덜 바쁜 시간에 유지하고 코딩 기술을 채택하여 그러한 스크립트의 성능.


코딩 팁 


마지막으로 이 섹션의 성능 및 메모리 사용을 최적화 하기 위해 코딩 측에서 수행 할 수 있는 작업 중 일부를 살펴 보겠습니다.


데이터베이스에서 라인 단위로 결과 읽기 


<?php // DATABASE SETTINGS define('DB_HOST', 'localhost'); define('DB_NAME', 'test'); define('DB_CHARSET', 'utf8'); define('DB_USER', 'root'); define('DB_PASSWORD', ''); // CONNECT TO DATABASE $pdo = new PDO( "mysql:host=" . DB_HOST . ";charset=" . DB_CHARSET .";dbname=" . DB_NAME, DB_USER, DB_PASSWORD, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false ] ) or die("Failed to connect to the database"); // SQL $stmt = $pdo->prepare("SELECT * FROM `test`"); $stmt->execute(); // FETCH ALL AT ONCE - THIS IS WHAT SOME PEOPLE DO // $results = $stmt->fetchAll(); // print_r($results); // FOR MASSIVE SETS, FETCH LINE-BY-LINE INSTEAD. while ($row = $stmt->fetch(PDO::FETCH_NAMED)) { print_r($row); } // CLOSE DATABASE CONNECTION if ($stmt !== null) { $stmt = null; } if ($pdo !== null) { $pdo = null; } // PEAK MEMORY USED echo "PEAK USAGE - " . memory_get_peak_usage() . "<br>"; ?> 


이것은 실제로 다소 일반적인 초보자 실수입니다. 백만 행의 데이터를 꺼내고 이를 한 번에 배열로 압축하려고 시도하는 중… 물론 끝이 나지 않습니다. 보다 현명한 방법은 행 단위로 데이터를 처리하는 것입니다.


파일을 한 줄씩 읽기 


<?php // TARGET FILE $source = "FILE.txt"; // THIS IS CONVENIENT - READ EVERYTHING INTO A STRING // $contents = file_get_contents($source); // print_r($contents); // FOR MASSIVE FILES, READ LINE-BY-LINE INSTEAD $handle = fopen($source, "r") or die("Failed to open " . $source); while (($line = fgets($handle)) !== false) { echo $line; } fclose($handle); // PEAK MEMORY USED echo "PEAK USAGE - " . memory_get_peak_usage() . "<br>"; ?> 


같은 오래된 이야기이지만 거대한 파일을 단일 문자열로 읽으려고 합니다. 대신 한 줄씩 읽으십시오.


소형 알고리즘 


<?php $varA = 123; $varB = 234; /* DON'T DO THIS $varC = 0; if ($varA > $varB) { $varC = $varA; } else { $varC = $varB; } */ // THIS IS BETTER $varC = $varA > $varB ? $varA : $varB ; // PEAK MEMORY USED echo "PEAK USAGE - " . memory_get_peak_usage() . "<br>"; ?> 


때때로, 우리는 어리석은 일을 하고 주변을 돌아 다니며… 따라서 스크립트를 수시로 검토하고 가능한 경우 단순화하십시오. 덜 혼란스러운 유선형 코드는 더 나은 성능과 같습니다.


유용성 변수 잘라 내기 


<?php /* DON'T DO THIS $varA = 123; $varB = 234; $varC = $varA + $varB; */ // IF $varA & $varB ARE NOT GOING TO BE USED ANYWHERE ELSE // THEN JUST DIRECTLY USE THE VALUE $varC = 123 + 234; // PEAK MEMORY USED echo "PEAK USAGE - " . memory_get_peak_usage() . "<br>"; ?> 


여러분 중 일부는 코드 닌자를 웃으면 서 이것을 "사소한"것으로 무시할 수 있습니다. 단일 변수는 얼마나 많은 메모리를 사용할 수 있습니까? 글쎄, 쓸모없는 변수가 많을수록 스크립트가 소비하는 메모리가 많아집니다. 거대한 프로젝트에서 이러한 쓸모없는 플래그와 변수 수백 가지를 유지하면 성능이 크게 저하되는 것을 볼 수 있습니다.


임시 플래그를 수동으로 제거 


<?php // IF YOU HAVE TO USE TEMPORARY VARIABLES FOR CALCULATIONS $varA = 123; $varB = 234; $varC = $varA + $varB; // YOU CAN REMOVE THEM WHEN THEY HAVE NO MORE USES unset($varA); unset($varB); gc_collect_cycles(); // CONTINUE TO DO YOUR THINGS // MAYBE GENERATE A REPORT ?> 


더 이상 임시 변수가 필요하지 않습니까? 정리해


데이터베이스에서 직접 출력 


<?php // DATABASE SETTINGS define('DB_HOST', 'localhost'); define('DB_NAME', 'test'); define('DB_CHARSET', 'utf8'); define('DB_USER', 'root'); define('DB_PASSWORD', ''); // CONNECT TO DATABASE $pdo = new PDO( "mysql:host=" . DB_HOST . ";charset=" . DB_CHARSET .";dbname=" . DB_NAME, DB_USER, DB_PASSWORD, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false ] ) or die("Failed to connect to the database"); // HTTP HEADERS header('Content-Type: application/octet-stream'); header("Content-Transfer-Encoding: Binary"); header("Content-disposition: attachment; filename=\"export.csv\""); // SQL $stmt = $pdo->prepare("SELECT * FROM `test`"); $stmt->execute(); // FETCH & DIRECTLY OUTPUT while ($row = $stmt->fetch(PDO::FETCH_NAMED)) { echo implode(",", $row) . "\r\n"; } // CLOSE DATABASE CONNECTION if ($stmt !== null) { $stmt = null; } if ($pdo !== null) { $pdo = null; } ?> 


보고서를 생성 할 때 일부 코드 닌자들은 데이터베이스에서 데이터를 먼저 배열로 가져 와서 해당 배열을 포맷 한 다음 출력합니다. 실제로 보다 효과적인 방법이 있습니다. 즉, 데이터베이스에서 읽을 때 직접 형식을 지정하고 출력하는 것입니다.


유용한 비트 


이 프로젝트의 전부입니다. 여기에 유용한 링크에 대한 작은 섹션이 있습니다.


참조 



댓글목록 0

등록된 댓글이 없습니다.

웹학교 로고

온라인 코딩학교

코리아뉴스 2001 - , All right reserved.