Takas alanından RAM'e çalışan tüm uygulamalar nasıl yeniden yüklenir?


20

Masaüstümün belleği tükenir ve çok fazla takas yaparsa, RAM'imi harcayan uygulamayı serbest bırakır veya öldürürüm. Ancak, bundan sonra, tüm masaüstü / uygulamalarım değiştirildi ve çok yavaş, masaüstümü / uygulamalarımı "değiştirmekten" (takas alanından RAM'e yeniden yükleme) bir yol biliyor musunuz?


Tüm sistemi swapon/ swapoff(şu anda kabul edilen yanıtın önerdiği gibi) kullanarak açmak yerine, ekran yöneticinizi ve tüm çocuklarını, işlem anılarını boşaltarak (değiştirmeyi zorlayan) açabilirsiniz. Ayrıca bkz . Stackoverflow'daki “Değiştirilmiş bir zsh işlemini takas etmeye zorlama?” .
zrajm

Yanıtlar:


16

Eğer gerçekten yeterince RAM'iniz varsa bu diziyi kullanabilirsiniz (root olarak):

$ swapoff -a
$ swapon -a

(tüm uygulamalarınızın açıkça değiştirilmesini sağlamak için)

(linux kullandığınızı varsayarsak)


IIRC yapmasanız bile mümkün olduğunca fazla veri taşıyacaktır. Iken önbellek ve co zarar verebilir. bazen yararlıdır.
Maciej Piechotka

19

Aşağıdaki hızlı ve kirli python betiği, bir işlemin belleğini stdout'a döker. Bunun, değiştirilen herhangi bir sayfayı veya eşlenen dosyayı yüklemenin yan etkisi vardır. Olarak Çağrı cat_proc_mem 123 456 789argümanlar süreç kimlikleri nerede.

Bu komut dosyası tamamen Linux'a özgüdür. Benzer bir /procyapıya (Solaris?) Sahip diğer sistemlere uyarlanabilir , ancak örneğin * BSD'de çalıştırmayı unutun. Hatta Linux üzerinde, sen tanımını değiştirmeniz gerekebilir c_pid_tve değerlerini PTRACE_ATTACHve PTRACE_DETACH. Bu, iyi programlama uygulamalarına bir örnek olarak değil, prensip kanıtıdır. Kendi sorumluluğunuzdadır kullanın.

Linux, bir işlemin belleğini kullanılabilir hale getirir /proc/$pid/mem. Yalnızca belirli adres aralıkları okunabilir. Bu aralıklar, metin dosyasından bellek eşleme bilgileri okunarak bulunabilir /proc/$pid/maps. Sahte dosya /proc/$pid/memokuma izni olan tüm işlemler tarafından okunamaz: okuyucu işlemi çağırmış olmalıdır ptrace(PTRACE_ATTACH, $pid).

#!/usr/bin/env python
import ctypes, re, sys

## Partial interface to ptrace(2), only for PTRACE_ATTACH and PTRACE_DETACH.
c_ptrace = ctypes.CDLL("libc.so.6").ptrace
c_pid_t = ctypes.c_int32 # This assumes pid_t is int32_t
c_ptrace.argtypes = [ctypes.c_int, c_pid_t, ctypes.c_void_p, ctypes.c_void_p]
def ptrace(attach, pid):
    op = ctypes.c_int(16 if attach else 17) #PTRACE_ATTACH or PTRACE_DETACH
    c_pid = c_pid_t(pid)
    null = ctypes.c_void_p()
    err = c_ptrace(op, c_pid, null, null)
    if err != 0: raise SysError, 'ptrace', err

## Parse a line in /proc/$pid/maps. Return the boundaries of the chunk
## the read permission character.
def maps_line_range(line):
    m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])', line)
    return [int(m.group(1), 16), int(m.group(2), 16), m.group(3)]

## Dump the readable chunks of memory mapped by a process
def cat_proc_mem(pid):
    ## Apparently we need to ptrace(PTRACE_ATTACH, $pid) to read /proc/$pid/mem
    ptrace(True, int(pid))
    ## Read the memory maps to see what address ranges are readable
    maps_file = open("/proc/" + pid + "/maps", 'r')
    ranges = map(maps_line_range, maps_file.readlines())
    maps_file.close()
    ## Read the readable mapped ranges
    mem_file = open("/proc/" + pid + "/mem", 'r', 0)
    for r in ranges:
        if r[2] == 'r':
            mem_file.seek(r[0])
            chunk = mem_file.read(r[1] - r[0])
            print chunk,
    mem_file.close()
    ## Cleanup
    ptrace(False, int(pid))

if __name__ == "__main__":
    for pid in sys.argv[1:]:
        cat_proc_mem(pid)

Ayrıca hakkında daha fazla bilgi edinin/proc/$pid/mem .

unswap () {
  cat_proc_mem "$@" >/dev/null
}

2
Bu, yığın borsasında gördüğüm en havalı şeylerden biri. Bunu göndermek için Kudos! Bundan çekilecek çok iyi külçe var.
Dan

Ne yazık ki bu komut dosyasını çalıştıramadım. Python 2 ile r [0] değerinin çok büyük olduğu hatasını gösterir. Python 3'te (birkaç küçük sorunu düzelttikten sonra) OSError alıyorum: [Errno 5] chunk = mem_file.read (r [1] - r [0]) 'da giriş / çıkış hatası ve her ikisinde de asılı kaldım vakalar.
barteks2x

@ Barteks2x Üzgünüm, bu senaryoyu hataya dayanıklı hale getirmek için şu an zamanım yok. En azından çok fazla güvenlik kısıtlaması olmayan makinelerde benim için işe yarıyor (teknik, sertleştirilmiş kurulumlarda devre dışı bırakılan bazı hata ayıklama arabirimlerini kullanıyor). Program, izlenirken askıya alınır, devam etmek için bir SIGCONT ( kill -CONT 1234burada 1234 PID'dir ) gönderin.
Gilles 'SO- kötü olmayı bırak'

Barteks2x @: ben hata kontrolu ekledik burada . Bu, komut dosyasının / dev / dri / card0'dan IOErrors ve [vsyscall] 'dan OverflowErrors üzerinde bile çalışmasını sağlar. (Ayrıca sorunlu alanın ne olduğunu da yazdırır).
hackerb9

6

Tamlık için GDB süreç imajını dökebilir. Tüm süreç hafızasını okumak için başka bir yol yoktur --- ben bunu unswaps olmadığını kontrol etmedi, ama zorundadır:
gdb -p $mypid
takip
(gdb) gcore /tmp/myprocess-core
Saved corefile /tmp/myprocess-core


3
gcore $pidayrıca gdb dışında da (küçük bir paket betiği olarak) kullanılabilir
Tobu

gcore, / dev / null dosyasına yazmanın bir yoluna sahip değildir; bu, bir işlemi belleğe geri zorlamaya çalıştığınız şeydir. Ancak, böyle tek bir komutla yapabilirsiniz: gdb --batch -p $pid -ex "gcore /dev/null" 2>/dev/null
hackerb9

0

swapon / swapoff takas alanınızı tamamen temizleyecektir, ancak bazılarını / proc dosya sistemi aracılığıyla da serbest bırakabilirsiniz. İlkini istiyorsun:

# To free pagecache
echo 1 > /proc/sys/vm/drop_caches

# To free dentries and inodes
echo 2 > /proc/sys/vm/drop_caches

# To free pagecache, dentries and inodes
echo 3 > /proc/sys/vm/drop_caches

http://linux-mm.org/Drop_Caches aracılığıyla


3
Takas belleği, tanım gereği önbellek değildir. Önbellekleri düşürmenin takastaki herhangi bir şeyi değiştirmesi pek olası değildir. Ayrıca, proc dosya sistemindeki dosyalar üzerine doğrudan yazmak yerine sysctl kullanmak tercih edilir. sysctl vm.drop_caches=X. Ayrıca, sysctl sudo yapmak daha kolaydır.
Juliano

@julian sanal bellek = ram + swap iirc. Hem uygulamalar hem de önbellekler sanal bellek kullanır. Bununla birlikte, operasyonun takastan önbellekler hariç her şeyi temizlemesi gerektiğini düşünüyorum , çünkü bunların gerçekten onu etkileyen şey olduğundan şüphe duyuyorum.
Ocak'ta xenoterracide

@xenoterracide: önbellekler yalnızca gerçek RAM belleğinde anlamlıdır. Önbelleği takasta saklamak anlamsızdır, tam zıttırlar. Takas, sistem fiziksel RAM yetersiz olduğunda kullanılan yavaş bellektir ; önbellek, sistemde çok fazla kullanılmayan fiziksel RAM olduğunda kullanılan hızlı bellektir .
Juliano

@juliano evet Biliyorum, ancak her ikisinin de sanal bellek kullanılarak saklandığına inanıyorum, ancak önbelleklerin yalnızca RAM'de saklanması mümkündür. dürüstçe önbellekleri bırakmak hiç mantıklı değil, imo.
Ocak'ta xenoterracide
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.