PHP의 가비지 컬렉트 시기

chadr의 이미지

php에서 변수를 할당하여 사용후 이 변수가 실제 시스템 메모리에서 해제가 되는 시기가 궁금합니다..

php에 스택이라는 개념이 있는것인지.. 아니면 모든 변수는 힙에 할당이 되어 자바와 같이 가비지컬렉터가 힙에서 해제를 해주는것인지.. 궁금합니다..

irondog의 이미지

답은 아니고....

php에 그런게 필요 할까요? 한페이지 출력하고 나면 종료 되는데 가비지 컬렉팅을 할 이유가 없어 보이는데요.

오히려 그런 복잡한 기능을 빼고 가볍기 때문에 웹에 많이 쓰는게 아닌가 싶은데요.

소타의 이미지

CGI모드나 modphp모드라면 윗분께서 설명해주신대로 스크립트가 종료되는 시점에 할당된 메모리가 해제됩니다.
문제는 fastcgi같은 형태일때가 문제인데요. 이때는 unset으로 변수의 메모리 해제를 요청하는 시점이 되겠습니다..

chadr의 이미지

가비지 컬랙팅 시기가 궁금한 이유는 다음과 같습니다..

현재 제가 유지보수를 하는 프로그램이 있습니다.. 이 프로그램이 php로 짜여있는데 cron으로 하루에 한번 작동하면서 데이터베이스에서 네트워크 장비들의 ip리스트를 받아와서 각 네트워크 장비들에게 snmp를 보내서 이 데이터를 가공하는 프로그램입니다.. 즉 웹프로그램은 아닙니다.

그런데 이 네트워크 장비들의 개수가 3000~4000개가 됩니다..
그러다보니 저 프로그램이 실행되고 어느정도 지나면 메모리 사용률이 1기가를 육박합니다;

제가 짠것도 아니고 현재 구동되는 시스템이라서 다른언어(C/C++)로 포팅을 하기에는 불가능한 상황입니다..

따라서 사용후 필요없는 메모리를 프로그래머가 강제로 해제를 시키거나 아니면 강제로 가비지 컬렉팅이 일어나도록 하는 방법이 궁금합니다..

Quote:
문제는 fastcgi같은 형태일때가 문제인데요. 이때는 unset으로 변수의 메모리 해제를 요청하는 시점이 되겠습니다..

php에서 unset이라는 함수를 이용하면 제가 하고자하는 것이 가능한지요?

ps. 가능하면 강제로 가비지 컬렉팅이 일어나게하는 방법이 알고 싶습니다..

-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

ibin의 이미지

chadr wrote:

php에서 unset이라는 함수를 이용하면 제가 하고자하는 것이 가능한지요?

ps. 가능하면 강제로 가비지 컬렉팅이 일어나게하는 방법이 알고 싶습니다..

저도 데이타변환, 특정동기화 작업, 메일링 발송시 메모리 문제로 고민한적이 있는데요.
사용이 끝난 변수들은 unset으로 바로 초기화시켜주는 방법으로 해결했습니다.

프로그램 중간 중간에 memory_get_usage() 를 사용해보면 현재 사용중인 메모리의 크기를 알 수 있으니 도움이 될겁니다.
http://kr.php.net/manual/kr/function.memory-get-usage.php

function()내에서 사용된 변수들은 실행이 끝나면 초기화되겠지만 그외에는 앞으로 사용될 변수인지 알 수 없는데 강제로 가비지 컬렉팅이 불가능하지 않을까요? :lol:

irondog의 이미지

2,3년 php가지고 놀아 봤습니다만 저도 가비지 컬렉팅 한다는 이야길 들어본적이 없습니다. 메뉴얼에도 찾아 볼 수가 없네요.

제 생각에 제일 좋은 방법은 shell script를 이용해서 php script의 반복 수행을 대치 하는 것이구요.

그게 힘들다면 unset 밖에는 별다른 수가 없을 것 같네요.
unset은 분명 메모리에서 변수를 파괴하는 기능을 합니다.

[정정합니다]

혹시나 해서 찾아 봤는데 가비지 컬렉터가 있네요.
http://www.faqts.com/knowledge_base/view.phtml/aid/11723

헌데 가비지 컬랙터를 가지고 있는 모든 언어가 그렇듯이 사용 후에는 참조를 없애줘야 가비지 컬랙팅이 일어 납니다.

익명 사용자의 이미지

irondog wrote:

...
헌데 가비지 컬랙터를 가지고 있는 모든 언어가 그렇듯이 사용 후에는 참조를 없애줘야 가비지 컬랙팅이 일어 납니다.

그 이야기는 맞지만, 그런 언어들은 강제로 GC가 일어나게 하는 방법을 제공하는 것이 _보통_입니다(대개의 경우 시스템 자체에서 메모리 할당이 필요할 때 조금씩 GC해보고 그래도 충분치 못하면 실제 할당 해버리죠). PHP가 그런지 아닌지는 모르겠지만, 그렇다 하더라도 PHP구현 GC의 질이 믿을 만 하다고는 생각지 않습니다.

chadr의 이미지

그런데 궁금한게 있습니다.. 제가 현재 문제로 삼고 있는 코드가 아래와 같은 형식입니다.

for ($i = 0; i < 1000; i++)
{
   $Data = $i;
}

이 경우에 $Data라는 변수가 매회 루프마다 $i값으로 치환이 될것입니다.. 이때 치환이 된 후의 $Data값이 실제 메모리상에서 삭제가 되는것인지.. 아니면

for ($i = 0; i < 1000; i++)
{
   $Data = $i;
   unset($Data);
}

을 하거나 php프로그램이 완전히 종료될때까지 메모리상에 남아있는지 궁금합니다.

-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

익명 사용자의 이미지

chadr wrote:
그런데 궁금한게 있습니다.. 제가 현재 문제로 삼고 있는 코드가 아래와 같은 형식입니다.

for ($i = 0; i < 1000; i++)
{
   $Data = $i;
}

이 경우에 $Data라는 변수가 매회 루프마다 $i값으로 치환이 될것입니다.. 이때 치환이 된 후의 $Data값이 실제 메모리상에서 삭제가 되는것인지.. 아니면

for ($i = 0; i < 1000; i++)
{
   $Data = $i;
   unset($Data);
}

을 하거나 php프로그램이 완전히 종료될때까지 메모리상에 남아있는지 궁금합니다.

php의 gc에 대해서는 잘 모릅니다만
$Data = $i 를 한 시점에서는 $Data와 $i는 메모리상의 같은 곳을 참조하게 되고요, 대신 해당하는 메모리의 ref_count가 2가 됩니다.
그런 상태에서 $i나 $Data의 값을 변경하게 되면 그때 실제로 값이 복사되고요, 그 시점에 원래 메모리의 ref_count가 다시 1이 됩니다. unset($Data); 하면 $Data가 참조한 공간의 ref_count가 다시 0이 되고... gc의 대상이 되겠네요.
여튼 ref_count가 0이 아니라면 스크립트 종료시까지 살아있는게 당연하겠네요
다른 언어는 어떤지 모르겠지만 $i = $Data 하는 시점에서 메모리가 복사되는건 아닙니다. $i = &$Data 이렇게 명시적으로 레퍼런스 하지 않더라도, 대입 후 값을 변경하기 전까지는 실제로 같은 곳을 참조한다고 합니다.
참고 : http://derickrethans.nl/php_references_article.php

sh.의 이미지

아이구 로긴이 안됬네요;; 윗글은 제가 썼습니다

chadr의 이미지

음.. 제 질문이 좀 애매했던것 같습니다..

제 질문의 요지는 이렇습니다.

"루프내에서 선언하여 사용한 변수가 루프가 끝난후에도 시스템 메모리에 살아있는가?" 입니다..

-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

sh.의 이미지

살아있습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.