Tại sao tôi không thể trao đổi với nhau khi có nhiều bộ nhớ?


10

Gần đây tôi đã nhận thấy rằng mặc dù có rất nhiều bộ nhớ trong hệ thống của tôi:

# free -m
             total       used       free     shared    buffers     cached
Mem:         15965       9680       6284         35       1754       2560
-/+ buffers/cache:       5365      10599
Swap:         2047        258       1789

Tôi không thể swapoff -avới hoán đổi 2G của mình

-rw-r----- 1 root root 2.0G Feb  9 21:34 /2GB.swap

Tôi đã thay đổi các tham số kernel sau thông qua sysctlnhưng đó là nguyên nhân:

vm.swappiness = 5
vm.vfs_cache_pressure = 200

Bất kỳ lý do cho:

# swapoff -a
swapoff: /2GB.swap: swapoff failed: Cannot allocate memory

? dmesgkhông đăng nhập bất cứ điều gì khi swapoffthất bại. Tôi đang sử dụng kernel linux 4.19.20-041920-generic.


Một ví dụ khác bao gồm /proc/meminfo

# cat /proc/meminfo
MemTotal:       16348296 kB
MemFree:         6673788 kB
MemAvailable:   11233052 kB
Buffers:          525048 kB
Cached:          2837788 kB
SwapCached:       362556 kB
Active:          4728244 kB
Inactive:        2758260 kB
Active(anon):    3132940 kB
Inactive(anon):  1043676 kB
Active(file):    1595304 kB
Inactive(file):  1714584 kB
Unevictable:        2396 kB
Mlocked:            2396 kB
SwapTotal:       2097148 kB
SwapFree:        1124272 kB
Dirty:               336 kB
Writeback:             0 kB
AnonPages:       3786868 kB
Mapped:           699944 kB
Shmem:             53116 kB
Slab:            1770268 kB
SReclaimable:    1578564 kB
SUnreclaim:       191704 kB
KernelStack:       47216 kB
PageTables:        82968 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:    10271296 kB
Committed_AS:   24712604 kB
VmallocTotal:   34359738367 kB
VmallocUsed:           0 kB
VmallocChunk:          0 kB
Percpu:             3552 kB
HardwareCorrupted:     0 kB
AnonHugePages:     26624 kB
ShmemHugePages:        0 kB
ShmemPmdMapped:        0 kB
CmaTotal:              0 kB
CmaFree:               0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
Hugetlb:               0 kB
DirectMap4k:      714480 kB
DirectMap2M:    13891584 kB
DirectMap1G:     3145728 kB

free -m

# free -m
             total       used       free     shared    buffers     cached
Mem:         15965       9447       6517         51        512       2771
-/+ buffers/cache:       6163       9801
Swap:         2047        950       1097

BIÊN TẬP

strace swapoff -a

root@MACHINE:~# strace swapoff -a
execve("/sbin/swapoff", ["swapoff", "-a"], [/* 22 vars */]) = 0
...
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=9469488, ...}) = 0
mmap(NULL, 9469488, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fd262737000
close(3)                                = 0
open("/proc/swaps", O_RDONLY)           = 3
fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd263a54000
read(3, "Filename\t\t\t\tType\t\tSize\tUsed\tPrio"..., 1024) = 102
readlink("/2GB.swap", 0x7ffcfbb3bea0, 4096) = -1 EINVAL (Invalid argument)
read(3, "", 1024)                       = 0
close(3)                                = 0
munmap(0x7fd263a54000, 4096)            = 0
swapoff("/2GB.swap")                    = -1 ENOMEM (Cannot allocate memory)
open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=2570, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd263a54000
read(3, "# Locale name alias data base.\n#"..., 4096) = 2570
read(3, "", 4096)                       = 0
close(3)                                = 0
munmap(0x7fd263a54000, 4096)            = 0
open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES/util-linux.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
...
open("/usr/share/locale-langpack/en/LC_MESSAGES/util-linux.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
write(2, "swapoff: ", 9swapoff: )                = 9
write(2, "/2GB.swap: swapoff failed", 25/2GB.swap: swapoff failed) = 25
write(2, ": ", 2: )                       = 2
open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
...
open("/usr/share/locale-langpack/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
write(2, "Cannot allocate memory\n", 23Cannot allocate memory
) = 23
open("/etc/fstab", O_RDONLY|O_CLOEXEC)  = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=838, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd263a54000
read(3, "# /etc/fstab: static file system"..., 4096) = 838
readlink("/2GB.swap", 0x7ffcfbb3c2b0, 4096) = -1 EINVAL (Invalid argument)
read(3, "", 4096)                       = 0
close(3)                                = 0
munmap(0x7fd263a54000, 4096)            = 0
exit_group(-1)                          = ?
+++ exited with 255 +++

Nếu hệ thống của bạn bị tráo đổi, việc xóa phân vùng trao đổi sẽ không giải quyết được bất kỳ vấn đề nào. Bạn sẽ chỉ tạo thêm các vấn đề (và BTW tốt hơn là sử dụng phân vùng, sau đó là tệp). Bạn có thể cần tìm ngay lập tức nơi các chương trình không hoán đổi dữ liệu vào tệp đó. Có lẽ bạn nên DỪNG các chương trình như vậy. Lưu ý: bộ nhớ bị phân mảnh có thể là một lý do. Hãy thử có lẽ cũng mất ít thời gian syncđể giảm các trang bẩn.
Giacomo Catenazzi

1
@GiacomoCatenazzi 1) Tại sao sử dụng phân vùng tốt hơn một tệp? 2) synckhông thay đổi việc sử dụng bộ nhớ một bit
Patryk

1
syncsẽ ghi các trang bẩn vào đĩa (không phải tất cả, nhưng khi các trang này sẽ nằm trên đĩa). Điều này làm cho các trang như vậy sạch sẽ, vì vậy chúng có thể được loại bỏ dễ dàng (không trao đổi, hoặc ghi vào đĩa), vì vậy kernel có thể nhanh chóng chuyển đổi một phần bộ nhớ từ bộ nhớ cache sang miễn phí. Đó là một mẹo rất ngắn hạn, để rút ngắn các giai đoạn quan trọng (hoán đổi / umount).
Giacomo Catenazzi

2
Phân vùng nằm trong sự kiểm soát trực tiếp của kernel (khối liền kề đơn, được căn chỉnh). Tệp: có nguy cơ không có đủ không gian liền kề hoặc can thiệp từ các tiện ích hệ thống khác). [và hệ thống tập tin gốc lý tưởng nên chỉ đọc]. [Và thường thì rất hữu ích khi có một phân vùng tạm thời, để khôi phục hệ thống hoặc để xử lý một số hệ thống "xâm lấn", đặc biệt là trên các máy từ xa hoặc các máy không có thiết bị khởi động dễ dàng]. Không phải là một yêu cầu khó, nhưng tôi thấy rất ít có vấn đề khi có một phân vùng đặc biệt cho điều đó [và đối với các máy RAID, bạn có thể hủy trao đổi, vì tốc độ]
Giacomo Catenazzi

1
Vấn đề vẫn là ... Có rất nhiều RAM miễn phí, nhiều hơn kích thước TOTAL của tệp hoán đổi. Tại sao không thể trao đổi bị vô hiệu hóa?
Paul Stelian

Câu trả lời:


1

Từ nghiên cứu trường hợp: Swapoff không thể phân bổ bộ nhớ .

Nếu các quy trình dự trữ nhiều bộ nhớ hơn tổng diện tích trao đổi và (một phần của) RAM và hệ thống của bạn được cấu hình để không quá bộ nhớ, việc phân bổ thất bại. Điều này có thể xảy ra ngay cả khi bạn có nhiều RAM miễn phí và không sử dụng bất kỳ trang nào trên khu vực trao đổi.


@Patryk, phần thừa của bạn được đặt là gì?
Daniel Farrell

0

Nếu tệp hoán đổi của bạn được xác định trong /etc/fstab(và không phải trong systemd-exchange), thì chỉ cần xóa hoặc nhận xét dòng trong /etc/fstabvà khởi động lại.

Nếu bạn đang sử dụng systemd-exchange để định cấu hình trao đổi, thì hãy đặt swapfc_enabled=0trong Swap File Chunkedphần /etc/systemd/swap.confvà khởi động lại.


Tôi không nghĩ rằng thực tế là bạn có thể đưa hệ thống lên mà không có tệp hoán đổi thực sự trả lời câu hỏi tại sao tệp hoán đổi, nếu nó được sử dụng, không thể tắt được.
ilkkachu

Khởi động lại là một giải pháp dễ dàng nếu nó có thể được dung thứ
Daniel Farrell
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.