레일스에서 메모리 관리 ..

43 views
Skip to first unread message

designerjune

unread,
Jul 26, 2010, 10:40:47 PM7/26/10
to 한국 루비 사용자 모임
안녕하세요, 레일스에서 메모리 관리 관련 해서 궁금한 점이 있습니다.

현재 운영하고 있는 사이트에서는 검색이 대부분을 이루고 있습니다.

리눅스 Centos 에 Ruby Enterprise 를 사용하고 있는데 메모리의 반환이 잘 이루어지는 것 같지가 않습니다.
메모리의 점유가 들쭉날쭉 해져서 불안불안 한 순간이 한두번이 아니거든요..

주로 검색이 이루어지는 소스 중 하나를 예를 들면, 주로 이런식으로 이루어져 있습니다.

recoreds = DataFind.find(:all,:conditions => ["id > ?",5002])

reault_arr = []
records.each do |record|
result_arr << record.no
end
records = nil if records.size > 0

일 경우에 제가 의도 한대로 records 가 메모리에 적재되어 있던 데이터베이스 값들을 비우는게 맞나요?
아니면 레일스단에서 명시적으로 메모리를 조절 할 수 있는 방법이 있는건가요?

여기저기 찾아보니 DataFind.clear_active_connections! 이렇게 하는것도 메모리 점유를 리턴하는 방법이
라고 하는데 이건 웬지 현재 활성화 되어 있는 연결을 끊는 것이지, 메모리에 관련된 건 아닌거 같거든요.

조언 부탁드립니다.

Kim Ki-yong

unread,
Jul 27, 2010, 12:00:21 AM7/27/10
to rub...@googlegroups.com
저도 메모리와 gc 와 관련해선 잘 모르지만..
일단은 메모리의 반환은 루비 vm 의 Garbage collection 에 의해서 이뤄지는 것으로 알고 있습니다.
Garbage collection 은 일반적으로 GC 알고리즘에서 “메모리가 필요하다고 판단될 때” 이뤄지며..
records = nil 을 한다고 메모리에서 해제되는 것이 아니라..
GC 알고리즘에 의해서(예를 들어 간단하게 reference count 가 0 이 된다던가..) GC 대상으로 선택되어져야 실제 메모리를 반환하는 것으로 알고 있습니다.
그러니 실제로는 gc 전까지 계속 메모리가 쌓이다가 gc 후 메모리가 떨어지는 상황이 반복되는 것이 맞는 것 같습니다.
이 상황이 문제가 될 정도로 크다면, 절대로 반환될 여지가 없는 메모리들이 쌓이게 되고 있는 건(Memory leak) 아닌지 점검해 볼 필요가 있을 것 같습니다.

그리고 예를 들어 주신 코드는..

> records = DataFind.find(:all,:conditions => ["id > ?",5002])
> result_arr = records.collect(:&no)


이런 식으로 접근하는 게 더 괜찮을 것 같습니다.

2010. 7. 27., 오전 11:40, designerjune 작성:

kkung

unread,
Jul 27, 2010, 12:07:40 AM7/27/10
to rub...@googlegroups.com

REE 최신 버전을 사용하고 계신다면,
GC관련 패치(Railsbench GC patch)가 적용 되어
GC관련 튜닝 파라메터를 적용할 수 있습니다.


위 내용 참고하시면 도움이 될 것 같네요 :)



2010/7/27 designerjune <eomjo...@gmail.com>

Sangmin Ryu

unread,
Jul 27, 2010, 12:19:40 AM7/27/10
to rub...@googlegroups.com
garbage collection 과 다른 관점으로 최적화의 문제 접근의 확장입니다. Kim Ki-young 님께서 비슷한
내용을 주셔서 거기에 첨언합니다.

1. Symbol#to_proc 오타 수정입니다.

> results = DataFind.find(:all, :conditions => ["id > ?",5002]).map(&:no)

See Also http://apidock.com/ruby/Symbol/to_proc 을 참고

최적화의 문제로 접근한다면,

2. DataFind 의 한 row가 부담되게 크다면, fetch 하실 column 데이터를 지정하는 방법도 있습니다.

> results = DataFind.find(:all, :select => "no", :conditions => ["id > ?",5002]).map(&:no)

3. fetch 양이 부담이시라면, find_each, find_in_batches 가 있습니다. 2번과 섞어 쓰면 됩니다.

> results = []
> DataFind.find_each(:all, :select => "no", :conditions => ["id > ?",5002]) do |df|
> results << df.no
> end

> results = []
> DataFind.find_in_batches(:all, :select => "no", :conditions => ["id > ?",5002]) do |group|
> results += group.map(&:no)
> end

see also http://api.rubyonrails.org/classes/ActiveRecord/Batches/ClassMethods.html
----
제 코드에도 오타가 있을수 있으니 (돌려본거 아닙니다.) ref 봐주세요.
----
Ruby Enterprise Edition에 적용된 GC는 patch는 다른 부께서 설명해 주시니 패스 합니다.

2010/7/26 Kim Ki-yong <unso...@gmail.com>:

--
http://neocoin.net

designerjune

unread,
Jul 27, 2010, 1:10:31 AM7/27/10
to 한국 루비 사용자 모임
답변 감사드립니다.
그런데, 절대로 반환될 여지가 없는 메모리라면 어떤게 있을까요??
저는 단순히 검색된 데이터를 인스턴스 변수화 하는것만 메모리에 쌓일거라고 단순하게 생각을 했더근요..

On 7월27일, 오후1시19분, Sangmin Ryu <neoc...@gmail.com> wrote:
> garbage collection 과 다른 관점으로 최적화의 문제 접근의 확장입니다. Kim Ki-young 님께서 비슷한
> 내용을 주셔서 거기에 첨언합니다.
>
> 1. Symbol#to_proc 오타 수정입니다.
>
> > results = DataFind.find(:all, :conditions => ["id > ?",5002]).map(&:no)
>

> See Alsohttp://apidock.com/ruby/Symbol/to_proc을 참고


>
> 최적화의 문제로 접근한다면,
>
> 2. DataFind 의 한 row가 부담되게 크다면, fetch 하실 column 데이터를 지정하는 방법도 있습니다.
>
> > results = DataFind.find(:all, :select => "no", :conditions => ["id > ?",5002]).map(&:no)
>
> 3. fetch 양이 부담이시라면, find_each, find_in_batches 가 있습니다. 2번과 섞어 쓰면 됩니다.
>
> > results = []
> > DataFind.find_each(:all, :select => "no", :conditions => ["id > ?",5002]) do |df|
> > results << df.no
> > end
> > results = []
> > DataFind.find_in_batches(:all, :select => "no", :conditions => ["id > ?",5002]) do |group|
> > results += group.map(&:no)
> > end
>

> see alsohttp://api.rubyonrails.org/classes/ActiveRecord/Batches/ClassMethods....


> ----
> 제 코드에도 오타가 있을수 있으니 (돌려본거 아닙니다.) ref 봐주세요.
> ----
> Ruby Enterprise Edition에 적용된 GC는 patch는 다른 부께서 설명해 주시니 패스 합니다.
>

> 2010/7/26 Kim Ki-yong <unsoul...@gmail.com>:

Sangmin Ryu

unread,
Jul 27, 2010, 1:26:07 AM7/27/10
to rub...@googlegroups.com
> 그런데, 절대로 반환될 여지가 없는 메모리라면 어떤게 있을까요??

그냥 일반론입니다.

이정도 생각해 볼수 있겠네요. 더 있을까요?

1. 대문자로 선언된 constant 데이터
2. @@로 선언된 class variable
3. 전역에 선언된 데이터

3번은 Rails 해당 사항도 없고, 접근하기도 힘드니 1,2 번 정도 일꺼 같은데, 마법과 같은 ruby 세상이라 더
있을지도 모르겠네요. :)

2010/7/26 designerjune <eomjo...@gmail.com>:

--
http://neocoin.net

Kim Ki-yong

unread,
Jul 27, 2010, 1:40:37 AM7/27/10
to rub...@googlegroups.com
좀 상대적이긴 한데..

어플리케이션에서 더 이상 사용되지는 않는 메모리지만, VM 이 사용하는 GC 알고리즘에 의해 GC 대상이 되지 않는다면 반환될 수 없겠죠.
예를 들어 reference count 만으로 GC 를 한다고 가정하면, 더 이상 사용되지는 않지만 reference count 가 0이 아닌 메모리들이 그 예겠죠.(이것 때문에 예전에 FLEX 할 때, 고생한 기억이 있습니다.)

메모리 leak 이 의심된다면, memory logging 을 할 수 있는 profiler 류의 도구를 이용해 가장 메모리를 많이 사용하고 있는 객체가 무엇인지 확인해 보면 좋을 것 같습니다.
아마 rails 플러그인으로도 로깅이나 모니터링 등등 의 다양한 도구들이 있을 겁니다.

2010. 7. 27., 오후 2:10, designerjune 작성:

Reply all
Reply to author
Forward
0 new messages