문제

루비 진정으로 기억하는 것이지만, 모든 비트의 가치가 있습니다.

메모리 사용량을 낮게 유지하기 위해 무엇을합니까? 큰 문자열을 피하고 대신 작은 배열/해시를 사용합니까, 아니면 걱정하고 쓰레기 수집가가 일을하도록하는 것이 문제가되지 않습니까?

편집하다:이 주제에 대한 좋은 기사를 찾았습니다 여기 - 오래되었지만 여전히 흥미 롭습니다.

도움이 되었습니까?

해결책

  1. 효율적인 표현 인 날짜 구조를 선택하고 잘 확장하며 필요한 작업을 수행하십시오.
  2. 부풀어 오르지 않고 더 쉬운 데이터 구조를 사용하여 작동하는 알고리즘을 사용하십시오.
  3. 다른 곳을 봐. 루비는 C 다리를 가지고 있으며 루비보다 C에서 기억을 의식하는 것이 훨씬 쉽습니다.

다른 팁

Phusion의 Ruby Enterprise Edition (많은 개선 된 쓰레기 수집이 포함 된 Mainline Ruby의 포크)을 발견하여 메모리 사용에 극적인 차이를 만들었습니다 ... 또한 그들은 매우 설치하기 쉽고 (그리고 당신을 제거 할 수있게 만들었습니다. 필요를 찾으십시오).

더 많은 것을 찾아서 다운로드 할 수 있습니다 그들의 웹 사이트.

나는 그것이 그렇게 많이 중요하다고 생각하지 않습니다. 메모리 소비를 향상시키기 위해 코드를 읽기 쉽게 만드는 데있어 필요 그것. 그리고 필요에 따라, 나는 a를 의미한다 특정 사례 성능 프로필 및 특정 지표 이는 모든 변경 사항이 문제를 해결할 것임을 나타냅니다.

메모리가 제한 요인이 될 애플리케이션이있는 경우 루비가 최선의 선택이 아닐 수도 있습니다. 즉, Rails 앱은 일반적으로 Mongrel 인스턴스 당 약 40-60MB의 RAM을 소비한다는 것을 알았습니다. 사물의 계획에서 이것은 그리 많지 않습니다.

JRUBY와 함께 JVM에서 응용 프로그램을 실행할 수 있습니다. Ruby VM은 현재 메모리 관리 및 쓰레기 수집을위한 JVM만큼 고급되지 않았습니다. 1.9 릴리스는 많은 개선 사항을 추가하고 있으며 대체 VM도 개발 중입니다.

루비 개발자들은 메모리를 스스로 관리 할 필요가 없기 때문에 운이 좋다.

Ruby는 물체를 할당하는 것 (예 : 예를 들어 단순한 것

100.times{ 'foo' }

100 개의 문자열 객체를 할당합니다 (문자열은 변이 가능하며 각 버전에는 자체 메모리 할당이 필요합니다).

많은 객체를 할당하는 라이브러리를 사용하는 경우 다른 대안을 사용할 수없고 선택하는 것이 쓰레기 수집기 비용을 지불 할 가치가 있는지 확인하십시오. (요청이 많지 않거나 요청 당 수십 명의 MS를 신경 쓰지 않을 수도 있습니다).

해시 객체 생성은 예를 들어 객체보다 더 많이 할당됩니다.

{'joe' => 'male', 'jane' => 'female'}

1 개 객체를 할당하지 않지만 7. (해시, 4 개의 문자열 + 2 개의 키 스트링)

상징 키가 쓰레기를 수집하지 않으므로 사용할 수있는 경우. 그러나 쓰레기가 수집되지 않기 때문에 사용자 이름을 기호로 변환하는 것과 같은 완전히 동적 키를 사용하지 않으려면 메모리를 '누출'합니다.

예시: 앱의 어딘가에, 당신은 다음과 같은 사용자 이름에 to_sym을 적용합니다.

hash[current_user.name.to_sym] = something

수백 명의 사용자가있을 때는 괜찮을 수 있지만 백만 명이있는 경우 어떻게됩니까? 숫자는 다음과 같습니다.

ruby-1.9.2-head >
# Current memory usage : 6608K
# Now, add one million randomly generated short symbols
ruby-1.9.2-head > 1000000.times { (Time.now.to_f.to_s).to_sym }

# Current memory usage : 153M, even after a Garbage collector run.

# Now, imagine if symbols are just 20x longer than that ?
ruby-1.9.2-head > 1000000.times { (Time.now.to_f.to_s * 20).to_sym }
# Current memory usage : 501M

이전에 비 통제 된 인수를 상징으로 변환하지 않거나 이전에 인수를 확인하지 않으면 서비스 거부로 이어질 수 있습니다.

또한 중첩 루프는 유지 보수가 어렵 기 때문에 3 단계 이상의 깊이를 피하십시오. 루프 및 기능의 중첩을 3 레벨 이하로 제한하는 것은 코드 수행자를 유지하는 좋은 경험 법칙입니다.

다음과 같은 링크는 다음과 같습니다.

http://merbist.com

http://blog.monitis.com

  1. Rails/Rack WebApp을 배포 할 때는 REE 또는 다른 사본이 쓰기 친화적 인 통역사를 사용하십시오.
  2. 쓰레기 수집기를 조정하십시오 (참조 https://www.engineyard.com/blog/tuning-the-garbage-collector-with-ruby-1-9-2 예를 들어)
  3. 추가 코드가 메모리를 사용하므로 사용하는 외부 라이브러리/보석 수를 줄이십시오.
  4. 실제로 메모리 집약적 인 앱의 일부가 있다면 C Extension에서 다시 작성하거나 다른/더 빠른/더 나은 최적화 된 프로그램을 호출하여 완료하는 것이 좋습니다 (방대한 양의 텍스트 데이터를 처리 해야하는 경우 아마도 해당 코드를 Grep, Awk, SED 등으로 대체 할 수 있습니다)

나는 루비 개발자가 아니지만 일부 기술과 방법은 어떤 언어에도 적용된다고 생각합니다.

작업에 적합한 최소 크기 변수를 사용하십시오
사용하지 않을 때 변수 및 연결을 파괴 및 닫습니다.
그러나 객체가있는 경우 많은 시간을 사용해야합니다. 큰 문자열 DP의 조작으로 루프를 스코프로 유지하는 것을 고려하고 더 작은 문자열의 작업을 한 다음 더 큰 문자열에 추가하십시오.

객체와 연결이 닫혀 있는지 확인하기 위해 괜찮은 (마침내 캐치를 시도하십시오) 오류 처리

데이터 세트를 처리 할 때만 필요한 최소값 만 반환합니다.

극단적 인 경우 외에 메모리 사용은 걱정할 것이 아닙니다. 메모리 사용을 줄이려고하는 시간은 많은 기가 바이트의.

보세요 작은 메모리 소프트웨어 - 메모리가 제한된 시스템 용 패턴. 당신은 어떤 종류의 메모리 제약 조건을 지정하지 않지만 나는 RAM을 가정합니다. Ruby 특정은 아니지만이 책에서 유용한 아이디어를 찾을 수 있다고 생각합니다. 패턴은 RAM, ROM 및 보조 스토리지를 다루며 작은 데이터 구조, 메모리 할당, 압축, 보조 스토리지 및 소규모의 주요 기술로 나뉩니다. 건축물.

우리가 실제로 걱정할 가치가있는 유일한 것은 Rmagick입니다.

해결책은 RMAGICK 버전 2를 사용하고 전화하는 것입니다. Image#destroy! 이미지를 사용하여 끝났을 때

다음과 같은 코드를 피하십시오.

str = ''
veryLargeArray.each do |foo|
  str += foo
  # but str << foo is fine (read update below)
end

각 중간 문자열 값을 문자열 객체로 생성 한 다음 다음 반복에 대한 유일한 참조를 제거합니다. 이것은 쓰레기를 수집 해야하는 점점 길고 긴 줄의 톤으로 메모리를 올립니다.

대신 사용하십시오 Array#join:

str = veryLargeArray.join('')

이것은 C에서 매우 효율적으로 구현되며 문자열 생성 오버 헤드가 발생하지 않습니다.

업데이트 : Jonas는 아래 의견에 맞습니다. 내 경고가 있습니다 += 하지만 <<.

나는 루비를 새롭게 새롭고 지금까지 나는 이와 관련하여 특별한 일을 할 필요가 없다는 것을 알지 못했습니다 (즉, 나는 일반적으로 프로그래머로서하는 경향이 있습니다). 어쩌면 이것은 메모리가 심각하게 최적화하는 데 걸리는 시간보다 저렴하기 때문일 수 있습니다 (루비 코드는 4-12GB의 RAM이있는 기계에서 실행됩니다). 내가 사용하는 작업이 장기적이지 않기 때문일 수도 있습니다 (즉, 응용 프로그램에 따라 다릅니다).

파이썬을 사용하고 있지만 전략이 비슷하다고 생각합니다.

소규모 기능/방법을 사용하려고 노력하므로 로컬 변수가 발신자로 돌아갈 때 자동으로 수집됩니다.

더 큰 기능/방법에서는 더 이상 필요하지 않을 때 큰 임시 객체 (예 : 목록)를 명시 적으로 삭제합니다. 가능한 빨리 자원을 닫는 것도 도움이 될 수 있습니다.

명심해야 할 것은 물체의 수명주기입니다. 당신이 대상이 그다지 전달되지 않으면, 쓰레기 수집가는 결국 시작하여 해방시킬 것입니다. 그러나 계속 참조하면 쓰레기 수집기가 해방하려면 약간의주기가 필요할 수 있습니다. 이것은 쓰레기 수집가가 마크 및 스윕 기술의 열악한 구현을 사용하는 Ruby 1.8에서 특히 그렇습니다.

오랫동안 메모리에 객체를 유지하는 데코레이터와 같은 "디자인 패턴"을 적용하려고 할 때이 상황이 발생할 수 있습니다. 고립 된 예제를 시도 할 때는 분명하지 않을 수 있지만, 수천 개의 객체가 동시에 생성되는 실제 응용 프로그램에서는 메모리 성장 비용이 중요합니다.

가능하면 다른 데이터 구조 대신 배열을 사용하십시오. 정수가 할 때 플로트를 사용하지 마십시오.

GEM/라이브러리 방법을 사용할 때주의하십시오. 메모리 최적화되지 않을 수 있습니다. 예를 들어 Ruby PG :: 결과 클래스에는 최적화되지 않은 '값'메소드가 있습니다. 추가 메모리를 많이 사용합니다. 나는 이것을 아직보고하지 않았다.

Malloc 교체 (3) 구현 제발 메모리 소비가 즉시 30%까지 줄어 듭니다. 나는 이것을 즉시 달성하기 위해 'Jemalloc'보석을 만들었습니다.

배열 및 목록 및 데이터 세트를 최대한 작게 유지하려고합니다. 창조와 쓰레기 수집은 대부분의 현대 언어로 매우 빠르기 때문에 개별 대상은 중요하지 않습니다.

경우 데이터베이스에서 일종의 거대한 데이터 세트를 읽어야하는 경우 전진/유일한 방식으로 읽고 약간의 비트로 처리해야합니다.

많은 기호를 사용하지 말고, 과정이 죽을 때까지 그들은 기억에 남아 있습니다. 이것은 상징이 쓰레기를 수집하지 않기 때문입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top