2013-05-09 3 views
6

루비에서 클래스에 할당 된 메모리의 크기를 확인하는 방법이 있습니까?바이트 단위의 클래스 크기

맞춤 클래스를 만들었으므로 메모리의 크기를 알고 싶습니다. 그래서 C에서 sizeof()의 모양을 가진 함수가 있습니까?

은 단순히 너무

test = MyClass.new 

같은 새로운 클래스를 초기화하는 메모리에 할당 된 클래스의 크기를 인쇄하는 방법을 찾기 위해 노력하고있다.

루비에서도 가능합니까?

+0

이 질문에는 최소한 두 가지 복잡한 점이 있습니다. 1) 개체의 모든 속성은 다른 클래스의 개체이기도하므로 포함되는지 여부를 명확히해야합니다. 2) 인스턴스 변수의 수와 유형은 Ruby에서 동적이므로 클래스의 메모리 크기와 같은 것은 없습니다. 그러나, 현재 객체에 할당 된 메모리를 이론적으로 측정 할 수 있습니다 (현재 어떻게, 또는 Ruby가 이것을 수행 할 수 있는지는 모르지만). –

답변

6

객체의 메모리 크기는 구현 의존 C.

과 같은 방법으로 클래스의 크기를 계산 어떤 언어 기능은 없습니다. 기본 클래스 객체의 구현에 따라 다릅니다. 또한 사용 된 메모리를 예측하는 것도 간단하지 않습니다. 예를 들어, 문자열은 짧을 경우 RString 구조체에 포함될 수 있지만 길이가 긴 경우 힙에 저장됩니다 (Never create Ruby strings longer than 23 characters).

일부 개체 취한 메모리는 다른 루비 구현을 표로되었습니다는 임의로 추가의 인스턴스 변수를 추가 할 수 있기 때문에 Memory footprint of objects in Ruby 1.8, EE, 1.9, and OCaml

마지막으로, 물체는 동일한 클래스 두 물체라도 다를 수있다, 어떤 인스턴스 변수가 하드 코딩되지 않습니다. 예를 들어, instance_variable_get


당신이 MRI 루비 1.9.2+ 사용하는 경우 instance_variable_set를 참조하십시오 당신이 개체의 일부만보고되는 것을 경고 (시도 할 수있는 방법이있다, 이것은로부터 명백하다 정수와 문자열이 제로 크기로 나타나는 사실) :

irb(main):176:0> require 'objspace' 
=> true 
irb(main):176:0> ObjectSpace.memsize_of(134) 
=> 0 
irb(main):177:0> ObjectSpace.memsize_of("asdf") 
=> 0 
irb(main):178:0> ObjectSpace.memsize_of({a: 4}) 
=> 184 
irb(main):179:0> ObjectSpace.memsize_of({a: 4, b: 5}) 
=> 232 
irb(main):180:0> ObjectSpace.memsize_of(/a/.match("a")) 
=> 80 

또한 memsize_of_all을 시도 할 수 있습니다 (이 전체 인터프리터의 메모리 사용에서 보이는 점에 유의하고, 변수를 덮어 쓰기하는 것은 이전 파일을 삭제 나타나지 않습니다 즉시) :

irb(main):190:0> ObjectSpace.memsize_of_all 
=> 4190347 
irb(main):191:0> asdf = 4 
=> 4 
irb(main):192:0> ObjectSpace.memsize_of_all 
=> 4201350 
irb(main):193:0> asdf = 4 
=> 4 
irb(main):194:0> ObjectSpace.memsize_of_all 
=> 4212353 
irb(main):195:0> asdf = 4.5 
=> 4.5 
irb(main):196:0> ObjectSpace.memsize_of_all 
=> 4223596 
irb(main):197:0> asdf = "a" 
=> "a" 
irb(main):198:0> ObjectSpace.memsize_of_all 
=> 4234879 

Ruby 인터프리터가 가비지 수집을 수행 할 때 아무런 보장이 없으므로주의해야합니다. 테스트와 실험을 위해 이것을 사용할 수도 있지만 프로덕션 환경에서는 사용하지 않는 것이 좋습니다!

+0

어때? X 수의 클래스를 초기화 한 다음 루비 인터프리터의 메모리 사용량을 앞뒤로 가져올 수 있습니까? 나는 각 클래스의 30 인스턴스 인 10 개의 연결이있을 경우 자체 스레드의 각 소켓에서 3 개의 클래스 (패킷 처리 등)를 하나씩 가져 오는 문제가 발생합니다. 이것이 근본적인 디자인 문제가 될지 궁금 해서요. 패킷 처리를 재 코딩하거나 생각해야 할 것입니다. 아니면 3 개의 클래스로 인해 메모리 사용량이 극히 적어지면 말입니다. –

+0

재미있는 결과가 나오는데, 간단히'puts ObjectSpace.memsize_of_all'을 실행하면'1180174'로 추정되는 값을 얻습니다. 그러나'(0..1000) .each do | i |를 실행하면; t.push PacketParser.new i; end'와'ObjectSpace를 놓습니다.memsize_of_all' 나는 920578'을 얻었고 이는 3000 개가 넘는 클래스를 초기화하지 않고서는 얻을 수 없었습니다. 여기 쓰레기 처리 외에 제가 누락 된 것이 있습니까? 실제로 3000 개의 클래스를 생성하는 것이 아니라 단순히 3 개의 클래스 또는 다른 것을 참조하는 것입니까? –

+0

나는 대답하기가 거의 불가능하다 - 모든 반복을 점검 할 수있다 (어쩌면 반복에서 갑작스런 감소를 볼 수있다). 위의 반복에서 객체에 대한 메모리를 할당하는 것만이 아니라는 사실을 알아야합니다. PacketParser 생성자 및 t.push 메서드는 (일시적으로) 메모리 사용을 증가시키는 로컬 변수를 할당 할 수도 있습니다. – ronalchn

관련 문제