U E D R S I H C RSS
ID
Password
Join
최상의 거울은 친구의 눈이다. ―게일족 속담


icon

Contents

1 시작하며
2 생성되는 객체들을 최소화하기
3 Freeing local variables

1 시작하며 #

많은 수의 객체들이 생성될 경우, 여러분의 시스템에 Garbage collection은 성능상의 문제를 야기할 수 있다. 이 글은 이 문제를 피하기위해 고안된 주제나 아이디어를 담고 있다.

2 생성되는 객체들을 최소화하기 #

질문: 나는 기본적으로 할당되는 임시메모리의 양을 최소화하기를 원한다. 그렇게 함으로써 GC가 호출되는 주기를 줄일 수 있을 것이라 생각한다. 이 주제에 대해서 누군가가 힌트를 줄수 있을까? 예를 들면, 만약 함수 A에 선언되어있는 지역변수들을 가지고 있다면, 함수 A가 호출될때마다 지역변수들이 메모리가 할당될 것인가?

답 : 그렇지 않다. 지역변수들은 스택에 저장된채로 유지되며, GC에 영향을 주지 않는다. 이런 구현들이 새로운 GC처리된 객체를 생성하는 경우이다.

  • {{a..b}} (단지 예제임; 생성되는 어떤 문자열 구축도 해당된다. 즉, 다시말하면 {{strsub()}} 또는 {{lua_pushstring()}} 까지도 포함된다) Each new string creates a new object.
각 "새로운" 문자열은 새로운 객체를 생성한다. 루아는 unique한 문자열들을 가진다. 이것은 각각의 사용가능한 문자열은 루아내에서는 단지 1개만 존재한다는 것을 뜻한다. 만약 신규 문자열이 생성되면, 루아는 먼저 문자열 풀내에 생성할 문자열이 이미 존재하는지 검사한다. 만약 존재한다면, 이미 저장되었던 문자열의 레퍼런스가 사용된다. 만일 존재하지 않는다면, 새로운 문자열 객체가 생성되고 문자열 풀에 등록된다. GC는 사용되지 않는 문자열들을 찾기위해 문자열 풀을 검사하고 그것들을 해제시킨다. 그래서 많은 수의 unique한 문자열을 생성하는 것은 GC를 다운시킬수 있다. 즉, 이것이 GC의 단점이다.
for i=1,100 do  x="foo"..tostring(i)  end  -- 100 개의 신규 문자열
주의: 코드 세그먼트들은 문자열 상수들을 참조하는 레퍼런스들을 담고있다. (위에서 "foo"를 참조해라) 함수가 존재하는 한 문자열은 문자열 풀내에 존재하게 된다; 이것은 함수가 실행될 때마다 각각 생성할 필요가 없다.

주의: Code segments hold references to strings constants (a la "foo" above). So the string will exist in the string pool as long as the function exists; it does not have to be created each time the function is executed.

  • {{ { ... } }} 매번 테이블이 생성될때마다 테이블 생성자가 실행된다. 가능한한 테이블을 재사용하도록 해라. You could even go as far as creating and using newtable/freetable functions that manage a pool of unused tables. 사용하지 않는 테이블의 풀을 관리하기 위해 newtable/freetable 함수들을 사용하고 생성... That way you get old style memory management for tables but you'll also get the old problems too ;-)


  • {{function() ... end}} Executing a function statement creates a closure (note: not calling the function but executing the function statement!). Normally no big impact on the GC but if you have function statements within a loop you may create a lot of garbage. I.e.:
    for i=1,100 do  foo(function() end)  end  -- bad for GC
    
    creates 100 function closures.

  • {{function(foo, ...) end}} Vararg functions create a table for the ellipsis (stored in '{{arg}}') each time the function is called.

  • userdata objects In Lua 4.0 (and 3.x) userdata objects are handled similar to strings. They are equal if the pointer value and the tag are equal.

  • {{dofile}}/{{dostring}} Well, these load/compile new code and will create strings and (GCed) code segments.

  • 3 Freeing local variables #


    Question (continuation of above): So any local string or table will be freed when you exit a function?

    Variables are a place to store objects (In fact, except for numbers it only holds pointers to the objects). Whether the stored object is a number or a table or anything else doesn't bother the variable. And local variables are not garbage collected objects themselves. So you may use them without creating intermediate objects. I think, that was what the original poster meant.

    "So you may use them without creating intermediate objects." Does this need clarification? The variable itself doesnt create a GC object but its value could. You can use local variables which reference other existing objects without creating objects that need to be collected. But, you can't create new objects which are locals without creating an object that needs to be collected later.

    About the objects stored within local variables: at the moment the local variable is no longer active the GC may collect the object that was stored there. The actual freeing of the object has nothing to do with function scopes or variable live times. The GC runs at certain times and frees all objects that are no longer accessible by any Lua code.

    Is this better written as: Variables (local and global) are Lua values. A value holds either a number or a _reference_ to a Lua object (eg. a table or function). Local variables are created on the stack (just like local variables in C) so the values themselves do not need garbage collecting. When a local variable is deleted, on exiting a function, nothing happens to an object that it referenced. The referenced object will only be freed when garbage collection occurs and there are no references from any variable to the object. It being freed has nothing to do with function scopes or variable live times. --Nick

    for i=1,100 do  x="foo"..tostring(i)  end  -- 100 new strings
    
    Question: What about if x is declared a local? Will only the last string assigned to x be freed when the function exits? And the other 99 strings be GC'd?

    No. Nothing special is done at function exit. All 100 strings will be garbage collected some time later after the function has terminated.

    Question: So if I have :
    function foo()
      local x = {"a", "b", "c"}
      x = {"d"}
    end
    
    Is {{ {"d"} }} freed when the function exits and {{ {"a", "b", "c"} }} will be GCed later?

    Same as above. Both tables are freed later by the GC. It is the only part of Lua that frees something and its policy is simple: free every-thing that is not reachable. And you can force a GC run by calling {{collectgarbage()}}.

    Valid XHTML 1.0! Valid CSS! powered by MoniWiki
    last modified 2010-10-28 12:42:52
    Processing time 0.4473 sec