일. 서언
이 글은 사실 지난 글의 메모리 최적화 부분이다.블로거의 php 프로그램이 실행될 때 오류를 보고합니다.
Out of memory (allocated 364904448) (tried) to allocate 262144 bytes)
1
즉, 전통적인 메모리가 부족하여 오류를 보고하는 것입니다. 문제는 내가 로컬로 설정한 메모리가 이미 1280M이라는 것입니다. 전혀 그렇지 않습니다.참을 수 있다. 그래서 여기서 한 단계씩 코드를 보면서 최적화가 필요한 부분을 적어본다. 주로 배열에 초점을 맞춘다.
2.최적화 전 준비
1,먼저 php의 현재 메모리 설정 보기
윈도: php.ini를 열고, 검색: memory_limit, 보통 12로 설정8M으로 충분하다
리눅스: php-i | grep Loaded Configurationio 실행"n File" 을 사용하여 해당 프로필을 찾습니다.
참고: 이 명령은 php 프로그램의 프로필 위치를 검색합니다. phpinfo를 열면 Lo가 표시됩니다.aded Configuration File 옵션, 대응
바로 php.ini 파일의 위치입니다.
2. php 배열이 차지하는 메모리 크기
참고:https://blog.csdn.net/hguisu/article/det에일스/7376705
어른들의 분석을 통해 알 수 있다.
(1) php는 배열에 대한 이용효율이 낮으며, 하나는 C언어에 100M의 메모리에 있는 배열로 PHP에 있다.1G로 할게요.
(2) php 빈 배열은 모두 14(zval) + 39(HashTable) + 33(ar)Buckets) = 86바이트
(3) php 메모리 보기 방법: memory_get_usage( ) , 구체적인 사용 방법: echo memory_get_usage(;)는 바로 이 방법으로 배열에 메모리 병목 현상이 발생했음을 확인하였다
3. 최적화 과정
1. 코드 중복
$arr = [];
foreach($response['hits']['hits'] as $v)
{
$arr[] = $v['_source'];
}
unset($v);
//원래 없던 일부 필드를 더해서 픽셀이 없는 데이터를 걸러낸다
foreach($arr as $key=>$v){
if(!array_key_exists('pixel.uuid',$v)){
unset($arr[$key]);
}
}
최적화 코멘트: 여기서 $arr은 완전히 불필요하다. 아래쪽에 있는 $response['hits']['hits']를 그대로 반복하면 된다. 만약 $arr가 매우 큰 배열이라면, 값을 매긴 후에 메모리를 하나 더 열어야 한다.그래서 되도록이면 안 되는 거죠.
2, 배열은 다른 빈 배열에 값을 할당한다
if(count($this->arrEsIndex) > 0){
unset($this->arrEsIndex);
$this->arrEsIndex = $arr;
}else{
$this->arrEsIndex = $arr;
}
최적화 리뷰: 이와 같은 배열 할당 작업은 최소화한다.$this->arrEsindex에 $arr을 할당한 후 $this->arrEsIndex의 값이 바뀌면 두 배가 되는 효과를 사용하기 때문이다.다음으로 값을 매긴 후, 이 $arr은 사실상 쓸모없지만, unset을 하지 않았기 때문에, 이 $arr은 여전히 메모리를 점유하고 있다.제안은 unset($arr), 즉 우리가 사용하지 않는 배열들을 제거하는 것이다.
정상적인 할당량은 메모리 소모가 일어나지 않지만 할당한 새 배열이 변경되면 php가 새 배열에 메모리를 할당해 불필요한 메모리 소모를 초래한다.직접 값을 할당하지 않는 것이 좋습니다. 만약 값을 할당하지 않으면, "&" 기호를 붙이고, 새로운 배열에 주소를 직접 전달하여 새로운 배열이 변경될 때 원래 메모리를 변경하는 것을 잊지 마십시오.
3. 배열을 함수에 전달한다.
$this->getScrollData($repos);
최적화 리뷰: 여기서 $repos는 배열이다.값전송 배열은 정상적으로도 가능하지만 이 배열 안에 있는 원소들이 만레벨이면 된다.
이 조작 역시 메모리 소모가 매우 크다.php 프로그램에서는 php를 전송하면 파라미터가 한 부씩 복사되기 때문에 값이 클수록 메모리 소모가 커진다.이러한 상황에 대응하여
클래스에서 글로벌 변수를 정의하고 함수체에서 $this->repos를 통해 이 배열을 조작하는 것이 좋습니다.인용하는 방식도 고려할 수 있습니다.& 를 사용하기 위해서, 과거의 일을 전달하기 위한 메모리 주소, 비트수는 그다지 크지 않습니다.
4. 판단조건을 순환외에 적어 매번 순환하는 일이 없도록 한다.
foreach($this->arrEsIndex as $k=>&$v) {
if (!empty($this->search_abtest_key) && $this->search_abtest_key != "is_50mclient") {
$v[$this->search_abtest_key] = 0;
}
}
최적화 리뷰: 이 조작에도 문제가 있습니다. if 조건이 충족되면 괜찮습니다.IF 조건이 충족되지 않으면 업무 차원에서 아예 이 부분을 조작할 필요가 없다.하지만 우리의 포르테흐는 가장 바깥쪽으로 순환하기 때문에 배열은 그대로 순환한다.문제는 이것이 매우 큰 배열이고 소모되는 메모리도 상당하다는 것이다.
5.unset은 비교적 큰 변수를 제거한다.
일부 큰 변수(256바이트보다 크면 좋음)에 대해서만 임시로 사용할 경우 사용 후 unset( )을 떨어뜨리는 것을 기억하십시오.변수를 '&'하여 참조하면 이 메모리의 참조 수가 증가합니다. 직접 unset() 변수는 즉시 변수를 방출하지 않습니다. unset은 연결이 끊어지기 때문입니다.변수에서 메모리 영역까지 연결하기이 메모리 영역의 인용 카운트를 -1로 하고, 그 인용을 대입한 변수까지 unset()이 떨어져야 메모리가 즉시 풀린다.
참고하다:https://blog.csdn.net/chaiyu2002/article/details/48002503
실례를 참고:https://www.jb51.net/article/30740.htm (결론 1과 결론 2)
6. 대용량 어레이 하나로 메모리를 너무 많이 소비하는 솔루션
문자열을 저장하는 방식으로 최적화하여배열을 사용할 때는문자열을 배열로 변환하기
7.순환 DB
이 문제는 늘 하던 얘기야, 블로거코드 안에 이게 안 나왔어상황은 그렇지만 모두가 주의를 기울이는 것이 비교적 좋다.DB를 순환적으로 끊임없이 조작하여 프로그램의 성능에 영향을 줍니다.
사. 총결산
이상의 최적화 부분도 블로거 한 걸음코드를 보면서 천천히 나아간다.화는 상대적으로 얕은 차원의 최적화다.하지만 이런 질문들도 알려주셔서 코드를 쓰고 기억하실 수 있습니다.다시 한 번 볼 수 있다면코드 작성을 시작할 때 성능에 신경을 써야 한다.최악의 경우라도 업무를 수행한 후, 코드를 다시 보고, 코드 구조를 최적화하고, 불필요한 변수를 제거하고, 너무 소모적인 것을 고칩니다.메모리의 조작.
블로거가 이곳을 최적화한 후, 원래의 세대.사이즈 1280M 안저장해 두어도 모자라 현재 128M의 메모리가 적당하다.프로그램이 실행되면 총 10M 정도의 메모리를 차지하게 된다.그래도 적당한 것 같아요.만약 여러분들도 메모리가 부족할 경우 php 메모리를 늘리는 것 외에 프로그램을 최적화하는 것도 고려해야 합니다.
'개발 꿀팁 > PHP' 카테고리의 다른 글
php 엑셀 파일 demo 읽기 및 python과의 성능 비교 (0) | 2022.07.21 |
---|---|
PHP의 CI 프레임워크 학습 (0) | 2022.07.21 |
php 대배열 순환 중첩의 성능 최적화 (0) | 2022.07.20 |
php 정적 페이지 생성 및 미리 보기 (0) | 2022.07.20 |
php가 QR코드를 생성하여 앞 페이지로 돌아가기 (0) | 2022.07.20 |