R bellek yönetimi / n Mb boyutunda vektör tahsis edemez


155

R'de büyük nesneleri kullanmaya çalışırken sorunlarla karşılaşıyorum. Örneğin:

> memory.limit(4000)
> a = matrix(NA, 1500000, 60)
> a = matrix(NA, 2500000, 60)
> a = matrix(NA, 3500000, 60)
Error: cannot allocate vector of size 801.1 Mb
> a = matrix(NA, 2500000, 60)
Error: cannot allocate vector of size 572.2 Mb # Can't go smaller anymore
> rm(list=ls(all=TRUE))
> a = matrix(NA, 3500000, 60) # Now it works
> b = matrix(NA, 3500000, 60)
Error: cannot allocate vector of size 801.1 Mb # But that is all there is room for

Bunun bitişik bellek bloklarını elde etmenin zorluğuyla ilgili olduğunu anlıyorum ( buradan ):

Başlayan hata mesajları, boyut vektörü tahsis edemez, bellek elde etme başarısızlığını belirtir, çünkü boyut bir işlem için adres alanı sınırını aşmıştır veya daha büyük olasılıkla, sistem belleği sağlayamamaktadır. 32 bitlik bir yapıda yeterli boş bellek olabileceğini, ancak onu eşlemek için yeterince büyük bir bitişik adres alanı bloğu olmadığını unutmayın.

Bunu nasıl aşabilirim? Benim asıl zorluğum betiğimde belirli bir noktaya gelmem ve R'nin bir nesneye 200-300 Mb ayıramaması ... Diğer işlemler için belleğe ihtiyacım olduğu için bloğu gerçekten önceden ayıramıyorum. Bu, gereksiz nesneleri özenle kaldırdığımda bile oluyor.

DÜZENLEME: Evet, üzgünüm: Windows XP SP3, 4Gb RAM, R 2.12.0:

> sessionInfo()
R version 2.12.0 (2010-10-15)
Platform: i386-pc-mingw32/i386 (32-bit)

locale:
[1] LC_COLLATE=English_Caribbean.1252  LC_CTYPE=English_Caribbean.1252   
[3] LC_MONETARY=English_Caribbean.1252 LC_NUMERIC=C                      
[5] LC_TIME=English_Caribbean.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

Kullanılmayan diğer işlemlerin hafızasını kaldırmak için 'ücretsiz' kullanmayı deneyin.
Manoel Galdino

5
@ Manoel Galdino: 'Ücretsiz' nedir? R işlevi mi?
Benjamin

3
@Manoel: R'de, hafızayı boşaltma görevi kullanıcı tarafından değil çöp toplayıcı tarafından gerçekleştirilir. C seviyesinde çalışıyorsanız, manuel olarak Callocve Freehafıza ile yapılabilir, ancak Benjamin'in yaptığı şeyin bu olmadığından şüpheleniyorum.
Sharpie

XML kitaplığında ücretsiz kullanabilirsiniz. Dokümantasyondan: "Bu genel işlev, verilen nesneyle ilişkili belleği açıkça serbest bırakmak için kullanılabilir. Otomatik sonlandırıcı işlevi / yordamı olmayan harici işaretçi nesnelerinde kullanılmak üzere tasarlanmıştır. yerel nesne. "
Manoel Galdino

Yanıtlar:


82

Tüm bu verilere gerçekten ihtiyacınız olup olmadığını düşünün veya matris seyrek olabilir mi? MatrixSeyrek matrisler için R'de ( örneğin pakete bakınız) iyi destek vardır .

Bu boyutta nesneler yapmanız gerektiğinde, R'deki diğer tüm işlemleri ve nesneleri minimumda tutun. gc()Şu anda kullanılmayan belleği temizlemek için kullanın veya daha iyisi yalnızca ihtiyacınız olan nesneyi bir oturumda oluşturun .

Yukarıdakiler yardımcı olamazsa, karşılayabileceğiniz kadar RAM'e sahip 64 bit bir makine edinin ve 64 bit R'yi yükleyin.

Bunu yapamazsanız, uzaktan bilgi işlem için birçok çevrimiçi hizmet vardır.

Bunu yapamazsanız, paket gibi ff(veya bigmemorySascha'nın bahsettiği gibi) bellek haritalama araçları yeni bir çözüm oluşturmanıza yardımcı olacaktır. Benim sınırlı deneyimime ffgöre daha gelişmiş paket, ancak High Performance ComputingCRAN Görev Görünümleri hakkındaki konuyu okumalısınız .


1
görev randomForest ile görüntü sınıflandırmasıdır. RandomForest'ı beslemek için eğitim verilerinin bir matrisine (60 banda kadar) ve 20.000 ila 6.000.000 satır arasında bir yere ihtiyacım var. Şu anda, yaklaşık 150.000 satırda maksimuma çıkıyorum çünkü sonuçta ortaya çıkan randomForest nesnesini tutmak için bitişik bir bloğa ihtiyacım var ... RandomForest bir matris nesnesine ihtiyaç duyduğundan bu yüzden bigmemory yardımcı olmuyor.
Benjamin

"İhtiyacınız olan nesneyi yalnızca bir oturumda oluşturun" derken neyi kastediyorsunuz?
Benjamin

sadece bir kez 'a' oluşturun, eğer ilk seferde yanlış yaparsanız yeni bir oturuma başlayın
mdsumner

1
Çok fazla hesaplamanın yapıldığı ancak çıktının nispeten küçük olduğu büyük döngüler içeren programlar için, döngünün iç bölümünü Rscript aracılığıyla (bir BASH veya Python Script'ten) çağırmak bellek açısından daha verimli olabilir. ve daha sonra sonuçları farklı bir komut dosyasında harmanlayın / toplayın. Bu şekilde, bellek her yinelemeden sonra tamamen serbest bırakılır. Döngüye aktarılan değişkenlerin yeniden yüklenmesi / yeniden hesaplanması nedeniyle bir miktar boşa harcanan hesaplama vardır, ancak en azından bellek sorununu çözebilirsiniz.
Benjamin

56

Windows kullanıcıları için aşağıdakiler, bazı bellek sınırlamalarını anlamama çok yardımcı oldu:

  • R'yi açmadan önce, Windows Kaynak Monitörü'nü açın (Ctrl-Alt-Sil / Görev Yöneticisini Başlat / Performans sekmesi / alt düğme 'Kaynak Monitörü' / Bellek sekmesine tıklayın)
  • Bize ne kadar RAM bellek göreceksiniz zaten açık Ar önce ve hangi uygulamalar tarafından kullanılan. Benim durumumda, toplam 4 GB'ın 1,6 GB'ı kullanılıyor. Yani R için sadece 2,4 GB alabileceğim, ama şimdi daha da kötüsü geliyor ...
  • R'yi açın ve 1,5 GB'lık bir veri kümesi oluşturun, ardından boyutunu 0,5 GB'a düşürün, Kaynak Monitörü RAM'imin yaklaşık% 95 oranında kullanıldığını gösteriyor.
  • gc()çöp toplama yapmak için kullan => işe yarıyor, bellek kullanımının 2 GB'a düştüğünü görebiliyorum

görüntü açıklamasını buraya girin

Makinemde çalışan ek tavsiyeler:

  • özellikleri hazırlayın, RData dosyası olarak kaydedin, R'yi kapatın, R'yi yeniden açın ve tren özelliklerini yükleyin. Kaynak Yöneticisi tipik olarak daha düşük bir Bellek kullanımı gösterir, bu da gc () bile tüm olası belleği kurtarmaz ve R'yi kapatmak / yeniden açmak, kullanılabilir maksimum bellekle başlamak için en iyi sonucu verir .
  • diğer numara ise sadece eğitim için tren setini yüklemektir (test setini yüklemeyin, bu tipik olarak tren setinin yarısı kadar olabilir). Eğitim aşaması hafızayı maksimum (% 100) kullanabilir, bu nedenle mevcut olan her şey yararlıdır. Tüm bunları, R bellek limitlerini denerken bir miktar tuzla almaktır.

11
R kendi başına çöp toplamayı yapar gc(), sadece bir illüzyondur. Görev yöneticisini kontrol etmek sadece çok basit bir Windows işlemidir. Kabul edebileceğim tek tavsiye .RData formatında kaydetme
David Arenburg

3
@DavidArenburg gc () bir illüzyon mu? Bu, bellek kullanımındaki düşüşü gösteren yukarıdaki resmin bir yanılsama olduğu anlamına gelir. Sanırım yanılıyorsun, ama yanılıyor olabilirim.
Timothée HENRY

4
Bunun gc()işe yaramayacağını söylemedim . Demek istediğim, R bunu otomatik olarak yapıyor, yani manuel olarak yapmanıza gerek yok. Buraya
David Arenburg

2
@DavidArenburg Yukarıdaki resimdeki bellek kullanımındaki düşüşün gc () komutundan kaynaklandığını söyleyebilirim. Gösterdiğiniz dokümanın, en azından benim kurulumum için doğru olduğuna inanmıyorum (Windows, R sürüm 3.1.0 (2014-04-10) Platform: i386-w64-mingw32 / i386 (32-bit)).
Timothée HENRY

15
Tamam, son kez. gc() ÇALIŞIYOR . Bunu kullanmanıza gerek yok çünkü R bunu dahili olarak yapıyor
David Arenburg


14

Bu sınırlamadan kaçınmanın en basit yolu 64 bit R'ye geçmektir.


26
Bu genel olarak bir tedavi değil - geçiş yaptım ve şimdi Error: cannot allocate vector of size ... Gbonun yerine var (ama evet, çok fazla veriye sahibim).
om-nom-nom

2
Belki bir tedavi değil ama çok yardımcı oluyor. Sadece RAM'e yükleyin ve memory.limit () 'i çalıştırmaya devam edin. Veya verilerinizi bölümlere ayırmayı / örneklemeyi düşünün.
random_forest_fanatic

64-bit'te bile sorun yaşıyorsanız, ki bu aslında sınırsızdır, muhtemelen daha büyük bir şeyi gerçekten devasa bir şey ayırmaya çalışıyorsunuzdur. Teorik olarak vektörün ne kadar büyük olması gerektiğini hesapladınız mı? Aksi takdirde, bilgisayarınızın daha fazla RAM'e ihtiyacı olabilir, ancak sahip olabileceğiniz çok fazla şey vardır.
hangmanwa7id

Daha fazla kafa kafaya çözümden önce bunun gibi basit çözümleri denemek güzel. Teşekkürler.
Nova

Dahası, bu yalnızca Windows ile ilgili bir sorun değildir. Şu anda Ubuntu üzerinde, Matrix kullanarak 64-bit R üzerinde çalışıyorum ve 20048 x 96448 Matrix nesnesini işlemekte zorluk çekiyorum.

14

Yardım sayfasını takip ettim memory.limitve bilgisayarımda R'nin varsayılan olarak ~ 1.5 GB'a kadar RAM kullanabileceğini ve kullanıcının bu limiti artırabileceğini öğrendim. Aşağıdaki kodu kullanarak,

>memory.limit()
[1] 1535.875
> memory.limit(size=1800)

sorunumu çözmeme yardımcı oldu.


3
Bu neden reddediliyor? elbette, bu tehlikeli bir yaklaşımdır, ancak çalışması için oturuma biraz daha fazla bellek ayrılması gerekiyorsa genellikle yardımcı olabilir.
Jeppe Olsen

3
Bu yalnızca Windows'a özel bir çözüm
Jinhua Wang

lol. İhtiyacım vardı memory.limit(size=7000). Windows 10 ve R x64, btw kullanıyorum.
Nip

@JeppeOlsen Bu neden tehlikeli bir yaklaşım?
melbez

12

Benzer bir sorunla karşılaştım ve 'ReadyBoost' olarak 2 flash sürücü kullandım. İki sürücü ek 8GB bellek artışı (önbellek için) sağladı ve sorunu çözdü ve ayrıca bir bütün olarak sistemin hızını artırdı. Readyboost'u kullanmak için sürücüye sağ tıklayın, özelliklere gidin ve 'ReadyBoost'u seçin ve' bu cihazı kullan 'radyo düğmesini seçin ve yapılandırmak için uygula veya Tamam'a tıklayın.


9

Komut dosyanızı linux ortamında çalıştırıyorsanız, bu komutu kullanabilirsiniz:

bsub -q server_name -R "rusage[mem=requested_memory]" "Rscript script_name.R"

ve sunucu, istenen belleği sizin için ayıracaktır (sunucu sınırlarına göre, ancak iyi bir sunucu ile hugefiles kullanılabilir)


1
Bunu bir Amazon EC2 bulut sunucusunda kullanabilir miyim? Öyleyse yerine ne koymalıyım server_name? Bunun içine çalıştırıyorum cannot allocate vector size...bir AMI üzerinde büyük Belge Vadeli Matrix yapmaya çalışıyor ve bu yeterli belleği yok neden çözemiyorum, veya ne kadar daha Kiralamak gerekiyor. Teşekkür ederim!
seth127

Ubuntu acemisiyim ve üzerinde Rstudio kullanıyorum. 16 GB RAM'im var. Cevapta gösterdiğiniz süreci nasıl uygularım? Teşekkürler
runjumpfly

3

Yukarıda bahsedilen kaydet / yükle yöntemi benim için çalışıyor. gc()Belleği nasıl / eğer birleştirir emin değilim ama bu işe yarıyor gibi görünüyor.

# defrag memory 
save.image(file="temp.RData")
rm(list=ls())
load(file="temp.RData")
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.