답변:
2009 년 설정되지 않은 매뉴얼 페이지에서 언급되었습니다 .
unset()
변수 이름을 설정합니다. 메모리를 즉시 해제하지 않습니다. PHP의 가비지 콜렉터는 CPU 사이클이 필요하지 않거나 스크립트가 메모리 부족으로 늦어지기 전에 늦게까지 의도적으로 적합 할 때이를 수행합니다.당신이하고 있다면
$whatever = null;
변수의 데이터를 다시 쓰고 있습니다. 메모리를 더 빨리 확보 / 축소 할 수 있지만 실제로 필요한 코드에서 CPU주기를 훔쳐서 전체 실행 시간이 길어질 수 있습니다.
(2013 년 이후로 해당 unset
매뉴얼 페이지 에는 해당 섹션이 더 이상 포함되지 않습니다)
php5.3까지 부모-자식 관계와 같이 순환 참조에 두 개의 객체가있는 경우 부모 객체에서 unset ()을 호출하면 자식 객체의 부모 참조에 사용 된 메모리가 해제되지 않습니다. (부모 객체가 가비지 수집 될 때 메모리가 해제되지 않습니다.) ( 버그 33595 )
" unset과 = null의 차이점 "이라는 질문에는 몇 가지 차이점이 자세히 설명되어 있습니다.
unset($a)
$a
기호 테이블에서 제거 합니다. 예를 들면 다음과 같습니다.
$a = str_repeat('hello world ', 100);
unset($a);
var_dump($a);
출력 :
Notice: Undefined variable: a in xxx
NULL
그러나 언제
$a = null
사용됩니까?
$a = str_repeat('hello world ', 100);
$a = null;
var_dump($a);
Outputs:
NULL
그 보인다
$a = null
조금 더 빨리 그보다unset()
기호 테이블 항목을 업데이트하면 빨리 제거보다 나타납니다 : 대응.
unset
) 변수 를 사용하려고 하면 오류가 발생하고 변수 표현식의 값이 널이됩니다. (PHP는 다른 무엇을해야합니까? 모든 표현식은 어느 정도 가치가 있어야합니다.)unset
실제로 함수는 아니지만 언어 구문 입니다. 더 이상 a return
또는 a보다 함수 호출이 아닙니다 include
.
성능 문제 외에도 unset
코드를 사용 하면 코드의 의도가 훨씬 명확 해집니다.
unset
와 같은 UnSeT
예를 들어,. 커뮤니티는 스타일 문제로 모두 소문자로 설정했지만 다른 케이스는 여전히 작동합니다.
변수에 대해 unset ()을 수행하면 본질적으로 변수를 '가비지 수집'(PHP에는 실제로는 없지만 예를 들어)으로 표시하므로 메모리를 즉시 사용할 수 없습니다. 변수는 더 이상 데이터를 저장하지 않지만 스택은 더 큰 크기로 유지됩니다. null 메서드를 수행하면 데이터가 삭제되고 스택 메모리가 거의 즉시 축소됩니다.
이것은 개인적인 경험과 다른 사람들로부터 온 것입니다. unset () 함수의 주석은 here을 참조하십시오 .
개인적으로 루프에서 반복 사이에 unset ()을 사용하므로 스택 크기가 지연 될 필요가 없습니다. 데이터는 사라졌지 만 설치 공간은 남아 있습니다. 다음 반복에서 메모리는 이미 PHP에 의해 취해지고 있으므로 다음 변수를 더 빨리 초기화합니다.
<?php
$start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
$a = 'a';
$a = NULL;
}
$elapsed = microtime(true) - $start;
echo "took $elapsed seconds\r\n";
$start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
$a = 'a';
unset($a);
}
$elapsed = microtime(true) - $start;
echo "took $elapsed seconds\r\n";
?>
"= null"이 더 빠를 것 같습니다.
PHP 5.4 결과 :
PHP 5.3 결과 :
PHP 5.2 결과 :
PHP 5.1 결과 :
PHP 5.0과 4.4에서는 상황이 다르게 보이기 시작합니다.
5.0 :
4.4 :
microtime (true)은 PHP 4.4에서 작동하지 않으므로 php.net/microtime / Example # 1에 제공된 microtime_float 예제를 사용해야했습니다.
unset
속도가 더 빠릅니다. 나중에 unset
사건의 존재를 확인하는 테스트가 있습니다. 이 테스트에서는 null
약간 더 빠릅니다. 테스트 : pastebin.com/fUe57C51
gc_collect_cycles
더 정확한 결과를 얻으려면 항상 타이머를 시작하기 전에 전화 하십시오.
배열 요소와 차이를 만듭니다.
이 예를 고려하십시오
$a = array('test' => 1);
$a['test'] = NULL;
echo "Key test ", array_key_exists('test', $a)? "exists": "does not exist";
여기에는 키 '테스트'가 여전히 존재합니다. 그러나이 예에서는
$a = array('test' => 1);
unset($a['test']);
echo "Key test ", array_key_exists('test', $a)? "exists": "does not exist";
키가 더 이상 존재하지 않습니다.
참조로 복사 된 변수에 대해 다른 방식으로 작동합니다.
$a = 5;
$b = &$a;
unset($b); // just say $b should not point to any variable
print $a; // 5
$a = 5;
$b = &$a;
$b = null; // rewrites value of $b (and $a)
print $a; // nothing, because $a = null
객체, 특히 지연로드 시나리오에서 가비지 콜렉터가 유휴 CPU 주기로 실행 중임을 고려해야하므로 많은 오브젝트가 작은 시간 페널티를로드 할 때 문제가 발생한다고 가정하면 메모리 확보가 해결됩니다.
GC가 메모리를 수집 할 수있게하려면 time_nanosleep을 사용하십시오. 변수를 null로 설정하는 것이 바람직합니다.
프로덕션 서버에서 테스트 한 결과 원래 작업이 50MB를 소비 한 후 중지되었습니다. nanosleep을 사용한 후 14MB는 일정한 메모리 소비였습니다.
PHP 버전에서 버전으로 변경 될 수있는 GC 동작에 따라 달라집니다. 그러나 그것은 PHP 5.3에서 잘 작동합니다.
예. 이 샘플 (VirtueMart2 Google 피드에서 가져온 코드)
for($n=0; $n<count($ids); $n++)
{
//unset($product); //usefull for arrays
$product = null
if( $n % 50 == 0 )
{
// let GC do the memory job
//echo "<mem>" . memory_get_usage() . "</mem>";//$ids[$n];
time_nanosleep(0, 10000000);
}
$product = $productModel->getProductSingle((int)$ids[$n],true, true, true);
...
나는 여전히 이것에 대해 의심하지만 스크립트에서 시도했지만 xdebug를 사용하여 앱 메모리 사용에 미치는 영향을 알고 있습니다. 스크립트는 다음과 같이 내 기능에 설정됩니다.
function gen_table_data($serv, $coorp, $type, $showSql = FALSE, $table = 'ireg_idnts') {
$sql = "SELECT COUNT(`operator`) `operator` FROM $table WHERE $serv = '$coorp'";
if($showSql === FALSE) {
$sql = mysql_query($sql) or die(mysql_error());
$data = mysql_fetch_array($sql);
return $data[0];
} else echo $sql;
}
그리고 return
코드 바로 앞에 unset을 추가 하고 나에게 160200을 주면 다음과 같이 변경하려고합니다.$sql = NULL
주고 그것을 바꾸려고하면 나에게 : 160224 :)
그러나 unset () 또는 NULL을 사용하지 않을 때이 비교에서 고유 한 것이 있습니다 .xdebug는 메모리 사용량으로 160144를 제공합니다.
따라서 unset () 또는 NULL을 사용하도록 줄을 지정하면 응용 프로그램에 프로세스가 추가되고 코드에서 원점을 유지하고 가능한 한 효과적으로 사용하는 변수를 줄이는 것이 좋습니다.
내가 틀렸다면 고쳐줘, 고마워
주석에서 언급했듯이 여기에 작성된 오류 (요소 재생성)가 있기 때문에 unset
and =null
에 대한 새로운 성능 테스트를 만들었습니다 . 지금은 중요하지 않은 것처럼 배열을 사용했습니다.
<?php
$arr1 = array();
$arr2 = array();
for ($i = 0; $i < 10000000; $i++) {
$arr1[$i] = 'a';
$arr2[$i] = 'a';
}
$start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
$arr1[$i] = null;
}
$elapsed = microtime(true) - $start;
echo 'took '. $elapsed .'seconds<br>';
$start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
unset($arr2[$i]);
}
$elapsed = microtime(true) - $start;
echo 'took '. $elapsed .'seconds<br>';
그러나 PHP 5.5.9 서버에서만 테스트 할 수 있습니다. 결과는 다음과 같습니다.-4.4571571350098 초 소요-4.4425978660583 초 소요
unset
가독성을 위해 선호 합니다.
PHP 7은 이미 그러한 메모리 관리 문제와 최소한의 사용으로 줄어 들었습니다.
<?php
$start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
$a = 'a';
$a = NULL;
}
$elapsed = microtime(true) - $start;
echo "took $elapsed seconds\r\n";
$start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
$a = 'a';
unset($a);
}
$elapsed = microtime(true) - $start;
echo "took $elapsed seconds\r\n";
?>
PHP 7.1 Outpu :
0.16778993606567 초 소요 0.16630101203918 초 소요
unset
즉각적인 메모리를 확보하지 않으면 코드는 여전히 매우 유용하며 메소드를 종료하기 전에 코드 단계를 전달할 때마다이를 수행하는 것이 좋습니다. 즉시 메모리를 비우는 것이 아니라는 점에 유의하십시오. 즉각적인 메모리는 CPU를위한 것이며, 보조 메모리는 RAM입니다.
또한 메모리 누수 방지에 대해서도 다룹니다.
이 링크를 참조하십시오 http://www.hackingwithphp.com/18/1/11/be-wary-of-garbage-collection-part-2
나는 오랫동안 오랫동안 설정 해제를 사용하고 있습니다.
이미 배열로 사용 된 모든 변수를 설정 해제하기 위해 코드에서 이와 같은 더 나은 방법.
$data['tesst']='';
$data['test2']='asdadsa';
....
nth.
그리고 just unset($data);
모든 변수의 사용을 해제합니다.
설정을 해제하려면 관련 항목을 참조하십시오
PHP에서 변수를 설정 해제하는 것이 얼마나 중요합니까?
[곤충]
기록을 위해, 그리고 걸리는 시간을 제외하고 :
<?php
echo "<hr>First:<br>";
$x = str_repeat('x', 80000);
echo memory_get_usage() . "<br>\n";
echo memory_get_peak_usage() . "<br>\n";
echo "<hr>Unset:<br>";
unset($x);
$x = str_repeat('x', 80000);
echo memory_get_usage() . "<br>\n";
echo memory_get_peak_usage() . "<br>\n";
echo "<hr>Null:<br>";
$x=null;
$x = str_repeat('x', 80000);
echo memory_get_usage() . "<br>\n";
echo memory_get_peak_usage() . "<br>\n";
echo "<hr>function:<br>";
function test() {
$x = str_repeat('x', 80000);
}
echo memory_get_usage() . "<br>\n";
echo memory_get_peak_usage() . "<br>\n";
echo "<hr>Reasign:<br>";
$x = str_repeat('x', 80000);
echo memory_get_usage() . "<br>\n";
echo memory_get_peak_usage() . "<br>\n";
반환
First:
438296
438352
Unset:
438296
438352
Null:
438296
438352
function:
438296
438352
Reasign:
438296
520216 <-- double usage.
결론 : 예상대로 널 (null) 및 설정되지 않은 사용 가능한 메모리 (실행이 끝날 때만). 또한 변수를 재 할당하면 특정 시점에서 값이 두 번 유지됩니다 (520216 대 438352).
$whatever
객체에 대한 포인트,$whatever = null
포인터를 덮어 객체 자체가 아니라, 그래서 그것은 기본적와 같은 역할을합니다unset()
.