Closed wooque closed 2 years ago
Seems it's always 250-300MB off, now it's
htop 3.0.5
Mem: 3.74G/14.5G
htop 3.1.0
Mem: 4.03G/14.5G
free -h
shows:
total used free shared buff/cache available
Mem: 14Gi 3.5Gi 7.4Gi 196Mi 3.6Gi 10Gi
@wooque could you paste the contents of your /proc/meminfo file here please? Also if your free(1) binary is from procps or procps-ng, which version of that package you're using? Thanks.
MemTotal: 15218400 kB
MemFree: 11451984 kB
MemAvailable: 13151248 kB
Buffers: 249420 kB
Cached: 1524404 kB
SwapCached: 0 kB
Active: 580628 kB
Inactive: 2435836 kB
Active(anon): 11784 kB
Inactive(anon): 1295384 kB
Active(file): 568844 kB
Inactive(file): 1140452 kB
Unevictable: 176 kB
Mlocked: 176 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 88 kB
Writeback: 0 kB
AnonPages: 1242904 kB
Mapped: 672504 kB
Shmem: 64520 kB
KReclaimable: 322528 kB
Slab: 407676 kB
SReclaimable: 322528 kB
SUnreclaim: 85148 kB
KernelStack: 11440 kB
PageTables: 27348 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 7609200 kB
Committed_AS: 9247788 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 40688 kB
VmallocChunk: 0 kB
Percpu: 9792 kB
HardwareCorrupted: 0 kB
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
ShmemPmdMapped: 0 kB
FileHugePages: 0 kB
FilePmdMapped: 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: 351936 kB
DirectMap2M: 6854656 kB
DirectMap1G: 8388608 kB
free
is from procps-ng 3.3.17
I don't know if it helps you, but out of curiosity I tried to run a git bisect
on this issue and I found that commit 3d497a3760626d398fffc8f4594e8b9658f67d55 seems to be the cause of this bug.
I was debugging a bit thanks to @asafkahlon pointer and the line that changes this behavior is https://github.com/htop-dev/htop/blob/main/MemoryMeter.c#L39, basically instead of printing used memory (values[0]) like before, it's printing total - available (values[4]). Why they differ and what is more correct?
@wooque I started trying to understand the differences you've reported based on all the numbers you've given, but soon realised each snapshot you've given is unrelated. I'd need to see (within a very short space of time) your /proc/slabinfo, free -mw and htop reported values (ideally for both text and bar meter modes) - i.e. with ideally just a second or two between the snapshots.
To answer your question about 'available', this is a value that was added to the kernel (/proc/meminfo MemAvailable field) in recent years and can be described as the amount of memory that is available for a new workload, without pushing the system into swap. It is the kernels best estimation of 'free' memory from MemFree, Active(file), Inactive(file), and SReclaimable, as well as the "low" watermarks from /proc/zoneinfo. If it is available, we use this to work backward and calculate the 'used' value which is reported in the bar meter mode.
There are several other things that differ slightly between htop and free (procps-ng) memory reporting - in htop we also incorporate hugepages in used/free calculations (doesn't seem to affect you based on your pasted /proc/meminfo), and we also adjust the Cached and Used values to avoid double accounting of Shmem (I don't believe procps does the latter from looking at the code - so that's another possible cause of difference for you).
I'll wait for @cgzones to chime in but from my code auditing I've not found a bug here so far. Without the correlated data I mentioned, I can't specifically point to the reason for the htop/free reporting difference for you however.
slabinfo
slabinfo - version: 2.1
# name <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
kvm_vcpu 0 0 8880 3 8 : tunables 0 0 0 : slabdata 0 0 0
kvm_mmu_page_header 0 0 184 22 1 : tunables 0 0 0 : slabdata 0 0 0
x86_emulator 0 0 2672 12 8 : tunables 0 0 0 : slabdata 0 0 0
fat_inode_cache 22 22 744 22 4 : tunables 0 0 0 : slabdata 1 1 0
fat_cache 0 0 40 102 1 : tunables 0 0 0 : slabdata 0 0 0
fuse_request 26 26 152 26 1 : tunables 0 0 0 : slabdata 1 1 0
fuse_inode 39 39 832 39 8 : tunables 0 0 0 : slabdata 1 1 0
ext4_groupinfo_4k 3003 3003 192 21 1 : tunables 0 0 0 : slabdata 143 143 0
ext4_fc_dentry_update 0 0 80 51 1 : tunables 0 0 0 : slabdata 0 0 0
ext4_inode_cache 20223 20223 1184 27 8 : tunables 0 0 0 : slabdata 749 749 0
ext4_allocation_context 224 224 144 28 1 : tunables 0 0 0 : slabdata 8 8 0
ext4_io_end 1088 1088 64 64 1 : tunables 0 0 0 : slabdata 17 17 0
ext4_extent_status 16422 16422 40 102 1 : tunables 0 0 0 : slabdata 161 161 0
jbd2_journal_handle 1387 1387 56 73 1 : tunables 0 0 0 : slabdata 19 19 0
jbd2_journal_head 2142 2142 120 34 1 : tunables 0 0 0 : slabdata 63 63 0
jbd2_revoke_table_s 512 512 16 256 1 : tunables 0 0 0 : slabdata 2 2 0
jbd2_revoke_record_s 1024 1024 32 128 1 : tunables 0 0 0 : slabdata 8 8 0
fsverity_info 0 0 256 32 2 : tunables 0 0 0 : slabdata 0 0 0
fscrypt_info 0 0 136 30 1 : tunables 0 0 0 : slabdata 0 0 0
MPTCPv6 0 0 2048 16 8 : tunables 0 0 0 : slabdata 0 0 0
ip6-frags 0 0 184 22 1 : tunables 0 0 0 : slabdata 0 0 0
PINGv6 0 0 1216 26 8 : tunables 0 0 0 : slabdata 0 0 0
RAWv6 234 234 1216 26 8 : tunables 0 0 0 : slabdata 9 9 0
UDPv6 192 192 1344 24 8 : tunables 0 0 0 : slabdata 8 8 0
tw_sock_TCPv6 0 0 248 33 2 : tunables 0 0 0 : slabdata 0 0 0
request_sock_TCPv6 0 0 304 26 2 : tunables 0 0 0 : slabdata 0 0 0
TCPv6 104 104 2432 13 8 : tunables 0 0 0 : slabdata 8 8 0
scsi_sense_cache 64 64 128 32 1 : tunables 0 0 0 : slabdata 2 2 0
bfq_io_cq 0 0 232 35 2 : tunables 0 0 0 : slabdata 0 0 0
bfq_queue 0 0 560 29 4 : tunables 0 0 0 : slabdata 0 0 0
mqueue_inode_cache 34 34 960 34 8 : tunables 0 0 0 : slabdata 1 1 0
kioctx 28 28 576 28 4 : tunables 0 0 0 : slabdata 1 1 0
userfaultfd_ctx_cache 0 0 192 21 1 : tunables 0 0 0 : slabdata 0 0 0
fsnotify_mark 0 0 72 56 1 : tunables 0 0 0 : slabdata 0 0 0
dnotify_struct 0 0 32 128 1 : tunables 0 0 0 : slabdata 0 0 0
pid_namespace 240 240 136 30 1 : tunables 0 0 0 : slabdata 8 8 0
UNIX 1320 1320 1088 30 8 : tunables 0 0 0 : slabdata 44 44 0
ip4-frags 0 0 200 20 1 : tunables 0 0 0 : slabdata 0 0 0
MPTCP 0 0 1856 17 8 : tunables 0 0 0 : slabdata 0 0 0
request_sock_subflow 0 0 376 21 2 : tunables 0 0 0 : slabdata 0 0 0
xfrm_state 0 0 768 21 4 : tunables 0 0 0 : slabdata 0 0 0
PING 0 0 1024 32 8 : tunables 0 0 0 : slabdata 0 0 0
RAW 256 256 1024 32 8 : tunables 0 0 0 : slabdata 8 8 0
tw_sock_TCP 264 264 248 33 2 : tunables 0 0 0 : slabdata 8 8 0
request_sock_TCP 0 0 304 26 2 : tunables 0 0 0 : slabdata 0 0 0
TCP 126 126 2240 14 8 : tunables 0 0 0 : slabdata 9 9 0
hugetlbfs_inode_cache 50 50 632 25 4 : tunables 0 0 0 : slabdata 2 2 0
dquot 256 256 256 32 2 : tunables 0 0 0 : slabdata 8 8 0
ep_head 2048 2048 16 256 1 : tunables 0 0 0 : slabdata 8 8 0
dax_cache 21 21 768 21 4 : tunables 0 0 0 : slabdata 1 1 0
bio_crypt_ctx 510 510 40 102 1 : tunables 0 0 0 : slabdata 5 5 0
request_queue 15 15 2144 15 8 : tunables 0 0 0 : slabdata 1 1 0
biovec-max 224 248 4096 8 8 : tunables 0 0 0 : slabdata 31 31 0
biovec-128 128 128 2048 16 8 : tunables 0 0 0 : slabdata 8 8 0
biovec-64 256 256 1024 32 8 : tunables 0 0 0 : slabdata 8 8 0
khugepaged_mm_slot 0 0 112 36 1 : tunables 0 0 0 : slabdata 0 0 0
user_namespace 182 182 624 26 4 : tunables 0 0 0 : slabdata 7 7 0
dmaengine-unmap-256 15 15 2112 15 8 : tunables 0 0 0 : slabdata 1 1 0
dmaengine-unmap-128 30 30 1088 30 8 : tunables 0 0 0 : slabdata 1 1 0
sock_inode_cache 1950 1950 832 39 8 : tunables 0 0 0 : slabdata 50 50 0
skbuff_ext_cache 2668 2982 192 21 1 : tunables 0 0 0 : slabdata 142 142 0
skbuff_fclone_cache 256 256 512 32 4 : tunables 0 0 0 : slabdata 8 8 0
skbuff_head_cache 1920 1920 256 32 2 : tunables 0 0 0 : slabdata 60 60 0
file_lock_cache 296 296 216 37 2 : tunables 0 0 0 : slabdata 8 8 0
file_lock_ctx 584 584 56 73 1 : tunables 0 0 0 : slabdata 8 8 0
net_namespace 35 35 4160 7 8 : tunables 0 0 0 : slabdata 5 5 0
buffer_head 145509 145509 104 39 1 : tunables 0 0 0 : slabdata 3731 3731 0
task_delay_info 510 510 80 51 1 : tunables 0 0 0 : slabdata 10 10 0
taskstats 184 184 352 23 2 : tunables 0 0 0 : slabdata 8 8 0
proc_dir_entry 1407 1407 192 21 1 : tunables 0 0 0 : slabdata 67 67 0
pde_opener 816 816 40 102 1 : tunables 0 0 0 : slabdata 8 8 0
proc_inode_cache 6325 6384 680 24 4 : tunables 0 0 0 : slabdata 266 266 0
seq_file 272 272 120 34 1 : tunables 0 0 0 : slabdata 8 8 0
bdev_cache 42 42 1536 21 8 : tunables 0 0 0 : slabdata 2 2 0
shmem_inode_cache 2578 2662 720 22 4 : tunables 0 0 0 : slabdata 121 121 0
kernfs_node_cache 40449 41184 128 32 1 : tunables 0 0 0 : slabdata 1287 1287 0
mnt_cache 825 825 320 25 2 : tunables 0 0 0 : slabdata 33 33 0
filp 8318 8896 256 32 2 : tunables 0 0 0 : slabdata 278 278 0
inode_cache 25090 25090 608 26 4 : tunables 0 0 0 : slabdata 965 965 0
dentry 64242 64470 192 21 1 : tunables 0 0 0 : slabdata 3070 3070 0
names_cache 72 72 4096 8 8 : tunables 0 0 0 : slabdata 9 9 0
lsm_inode_cache 56960 56960 32 128 1 : tunables 0 0 0 : slabdata 445 445 0
uts_namespace 111 111 432 37 4 : tunables 0 0 0 : slabdata 3 3 0
vm_area_struct 49185 57600 200 20 1 : tunables 0 0 0 : slabdata 2880 2880 0
mm_struct 240 240 1088 30 8 : tunables 0 0 0 : slabdata 8 8 0
files_cache 253 253 704 23 4 : tunables 0 0 0 : slabdata 11 11 0
signal_cache 476 476 1152 28 8 : tunables 0 0 0 : slabdata 17 17 0
sighand_cache 420 420 2112 15 8 : tunables 0 0 0 : slabdata 28 28 0
task_struct 693 820 8064 4 8 : tunables 0 0 0 : slabdata 205 205 0
cred_jar 1764 1764 192 21 1 : tunables 0 0 0 : slabdata 84 84 0
anon_vma_chain 31669 46400 64 64 1 : tunables 0 0 0 : slabdata 725 725 0
anon_vma 18946 29624 88 46 1 : tunables 0 0 0 : slabdata 644 644 0
pid 2016 2016 128 32 1 : tunables 0 0 0 : slabdata 63 63 0
Acpi-Operand 5600 5600 72 56 1 : tunables 0 0 0 : slabdata 100 100 0
Acpi-ParseExt 312 312 104 39 1 : tunables 0 0 0 : slabdata 8 8 0
Acpi-State 459 459 80 51 1 : tunables 0 0 0 : slabdata 9 9 0
numa_policy 1360 1360 24 170 1 : tunables 0 0 0 : slabdata 8 8 0
perf_event 216 216 1192 27 8 : tunables 0 0 0 : slabdata 8 8 0
trace_event_file 4048 4048 88 46 1 : tunables 0 0 0 : slabdata 88 88 0
ftrace_event_field 9690 9690 48 85 1 : tunables 0 0 0 : slabdata 114 114 0
pool_workqueue 1856 1856 256 32 2 : tunables 0 0 0 : slabdata 58 58 0
radix_tree_node 15608 16492 584 28 4 : tunables 0 0 0 : slabdata 589 589 0
task_group 225 225 640 25 4 : tunables 0 0 0 : slabdata 9 9 0
vmap_area 8846 9408 64 64 1 : tunables 0 0 0 : slabdata 147 147 0
dma-kmalloc-8k 0 0 8192 4 8 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-4k 0 0 4096 8 8 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-2k 0 0 2048 16 8 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-1k 0 0 1024 32 8 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-512 0 0 512 32 4 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-256 0 0 256 32 2 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-128 0 0 128 32 1 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-64 0 0 64 64 1 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-32 0 0 32 128 1 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-16 0 0 16 256 1 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-8 0 0 8 512 1 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-192 0 0 192 21 1 : tunables 0 0 0 : slabdata 0 0 0
dma-kmalloc-96 0 0 96 42 1 : tunables 0 0 0 : slabdata 0 0 0
kmalloc-rcl-8k 0 0 8192 4 8 : tunables 0 0 0 : slabdata 0 0 0
kmalloc-rcl-4k 0 0 4096 8 8 : tunables 0 0 0 : slabdata 0 0 0
kmalloc-rcl-2k 0 0 2048 16 8 : tunables 0 0 0 : slabdata 0 0 0
kmalloc-rcl-1k 128 128 1024 32 8 : tunables 0 0 0 : slabdata 4 4 0
kmalloc-rcl-512 64 64 512 32 4 : tunables 0 0 0 : slabdata 2 2 0
kmalloc-rcl-256 32 32 256 32 2 : tunables 0 0 0 : slabdata 1 1 0
kmalloc-rcl-192 21 21 192 21 1 : tunables 0 0 0 : slabdata 1 1 0
kmalloc-rcl-128 224 224 128 32 1 : tunables 0 0 0 : slabdata 7 7 0
kmalloc-rcl-96 462 462 96 42 1 : tunables 0 0 0 : slabdata 11 11 0
kmalloc-rcl-64 4608 4608 64 64 1 : tunables 0 0 0 : slabdata 72 72 0
kmalloc-rcl-32 0 0 32 128 1 : tunables 0 0 0 : slabdata 0 0 0
kmalloc-rcl-16 0 0 16 256 1 : tunables 0 0 0 : slabdata 0 0 0
kmalloc-rcl-8 0 0 8 512 1 : tunables 0 0 0 : slabdata 0 0 0
kmalloc-cg-8k 32 32 8192 4 8 : tunables 0 0 0 : slabdata 8 8 0
kmalloc-cg-4k 178 200 4096 8 8 : tunables 0 0 0 : slabdata 25 25 0
kmalloc-cg-2k 288 288 2048 16 8 : tunables 0 0 0 : slabdata 18 18 0
kmalloc-cg-1k 992 992 1024 32 8 : tunables 0 0 0 : slabdata 31 31 0
kmalloc-cg-512 1761 1792 512 32 4 : tunables 0 0 0 : slabdata 56 56 0
kmalloc-cg-256 256 256 256 32 2 : tunables 0 0 0 : slabdata 8 8 0
kmalloc-cg-192 273 273 192 21 1 : tunables 0 0 0 : slabdata 13 13 0
kmalloc-cg-128 0 0 128 32 1 : tunables 0 0 0 : slabdata 0 0 0
kmalloc-cg-96 336 336 96 42 1 : tunables 0 0 0 : slabdata 8 8 0
kmalloc-cg-64 512 512 64 64 1 : tunables 0 0 0 : slabdata 8 8 0
kmalloc-cg-32 1024 1024 32 128 1 : tunables 0 0 0 : slabdata 8 8 0
kmalloc-cg-16 2048 2048 16 256 1 : tunables 0 0 0 : slabdata 8 8 0
kmalloc-cg-8 4096 4096 8 512 1 : tunables 0 0 0 : slabdata 8 8 0
kmalloc-8k 189 200 8192 4 8 : tunables 0 0 0 : slabdata 50 50 0
kmalloc-4k 768 800 4096 8 8 : tunables 0 0 0 : slabdata 100 100 0
kmalloc-2k 1024 1024 2048 16 8 : tunables 0 0 0 : slabdata 64 64 0
kmalloc-1k 2863 3552 1024 32 8 : tunables 0 0 0 : slabdata 111 111 0
kmalloc-512 9889 10240 512 32 4 : tunables 0 0 0 : slabdata 320 320 0
kmalloc-256 4890 4992 256 32 2 : tunables 0 0 0 : slabdata 156 156 0
kmalloc-192 8279 9891 192 21 1 : tunables 0 0 0 : slabdata 471 471 0
kmalloc-128 2240 2240 128 32 1 : tunables 0 0 0 : slabdata 70 70 0
kmalloc-96 2688 2688 96 42 1 : tunables 0 0 0 : slabdata 64 64 0
kmalloc-64 15380 15808 64 64 1 : tunables 0 0 0 : slabdata 247 247 0
kmalloc-32 18688 18688 32 128 1 : tunables 0 0 0 : slabdata 146 146 0
kmalloc-16 11776 11776 16 256 1 : tunables 0 0 0 : slabdata 46 46 0
kmalloc-8 10752 10752 8 512 1 : tunables 0 0 0 : slabdata 21 21 0
kmem_cache_node 448 448 64 64 1 : tunables 0 0 0 : slabdata 7 7 0
kmem_cache 288 288 256 32 2 : tunables 0 0 0 : slabdata 9 9 0
free -mw
total used free shared buffers cache available
Mem: 14861 1489 11677 45 91 1603 13044
Swap: 0 0 0
htop
@wooque its /proc/meminfo we need to analyse this, not /proc/slabinfo. Thanks!
meminfo
MemTotal: 15218404 kB
MemFree: 5633168 kB
MemAvailable: 9050148 kB
Buffers: 397116 kB
Cached: 3165444 kB
SwapCached: 0 kB
Active: 1661508 kB
Inactive: 5360800 kB
Active(anon): 40992 kB
Inactive(anon): 3571772 kB
Active(file): 1620516 kB
Inactive(file): 1789028 kB
Unevictable: 144 kB
Mlocked: 144 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 520 kB
Writeback: 0 kB
AnonPages: 3459980 kB
Mapped: 1140440 kB
Shmem: 187540 kB
KReclaimable: 339844 kB
Slab: 465288 kB
SReclaimable: 339844 kB
SUnreclaim: 125444 kB
KernelStack: 17936 kB
PageTables: 51144 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 7609200 kB
Committed_AS: 16363948 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 49076 kB
VmallocChunk: 0 kB
Percpu: 12288 kB
HardwareCorrupted: 0 kB
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
ShmemPmdMapped: 0 kB
FileHugePages: 0 kB
FilePmdMapped: 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: 2238144 kB
DirectMap2M: 11259904 kB
DirectMap1G: 2097152 kB
free
total used free shared buffers cache available
Mem: 14861 5549 5501 183 387 3423 8838
Swap: 0 0 0
htop
@wooque OK, I've checked all the values and done all the calculations by hand now and I understand what's happening.
It'd be very helpful to get @cgzones opinion here as to why it was changed, because personally I think the htop behaviour is a bit confusing now.
Internally in htop we have a value of usedMem that matches what free(1) is reporting. As you found, this is being discarded in the case of the MemoryMeter 'Bar' mode if "available" exists - however, we do not change the 'used' value in this way when a MemoryMeter is in 'Text' mode (which has more details incl. 'available'). At the very least reporting two different 'used' memory values within htop in the two different modes is confusing.
So, I'll open a PR to change is back (which will then make the 'used' bar mode match with free) and continue to seek details on whether I've missed something re what @cgzones was trying to do in commit 3d497a3760626d398fffc8f4594e8b9658f67d55 where on one hand it says "match with procps free" but at the same time, in bar mode only, it calculates its own slightly-different value for 'used'.
The idea in 3d497a3760626d398fffc8f4594e8b9658f67d55 with
Use total minus available memory instead of manually computed used-memory as fraction part in bar mode (if available).
was to utilize the Linux 3.14+ memory information MemAvailable.
In bar mode the memory types (used/cached/buffered) are display in different colors and the textual bit is a broad overview. The actual used fraction can be guessed by the size of the first bar section (by color) or explicitly seen in text mode. As overview information I find total - available
more interesting than used
.
@cgzones thanks - yeah, I figured it was something like that. I think in practice we're going to have this problem where users cannot reconcile the numbers they say with free(1) or even htop itself in the alternate meter mode. So the risk vs reward barrier would have to be quite high for us to do 'something special' like this, and in this case I'm not sure its the right thing to do.
But, maybe its just me - happy to hear other points of view on this.
maybe adding used vs total-available behind a setting
procps (free, top,...) also switched to calculate used as total - available: https://gitlab.com/procps-ng/procps/-/commit/2184e90d2e7cdb582f9a5b706b47015e56707e4d
htop 3.0.5
Mem: 789M/14.5Ghtop 3.1.0
Mem: 1.04G/14.5Gfree -h
shows: