- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
免责声明 我不确定我使用的术语是否正确。它可能不是 Optree 造成下面提到的膨胀:它可能是 DynaLoader
加载的符号。没有被释放。
是否可以使用模块,例如 POSIX.pm
,卸载它并减少(收缩或修剪)optree,而不需要任何一个
我尝试过的事情
这是一个简单的测试,创建一个文件 test.pl
$|++;
use Symbol;
use Class::Unload;
use POSIX;
print "GOT POSIX";
sleep(3);
no POSIX;
Class::Unload->unload('POSIX');
Symbol::delete_package('POSIX');
print "unloaded";
sleep(3);
外壳命令
perl ./test.pl & watch -n1 'ps -C perl -o "cmd rss";'
您可能会或可能不会看到 RSS 大小的增加(POSIX 可能会在 watch
生成 ps
之前加载)。但是,我希望看到它缩小。
追踪到底是什么 POSIX.pm
我看到它使用 XSLoader
它使用 DynaLoader
.
在 /proc/$$/smaps
中进行一些快速比较检查我已经确定使用 POSIX.pm 会导致代表空间差异的堆分配。使用 POSIX.pm 时,堆上的第一个分配要大得多:
56122fe4c000-561230040000 rw-p 00000000 00:00 0 [heap]
Size: 2000 kB
Rss: 1956 kB
Pss: 1956 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 1956 kB
Referenced: 1956 kB
Anonymous: 1956 kB
AnonHugePages: 0 kB
ShmemPmdMapped: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB
SwapPss: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Locked: 0 kB
VmFlags: rd wr mr mw me ac sd
对比
560c9f6ba000-560c9f6fc000 rw-p 00000000 00:00 0 [heap]
Size: 264 kB
Rss: 220 kB
Pss: 220 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 220 kB
Referenced: 220 kB
Anonymous: 220 kB
AnonHugePages: 0 kB
ShmemPmdMapped: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB
SwapPss: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Locked: 0 kB
VmFlags: rd wr mr mw me ac sd
我已经确认了一些事情,破坏命名空间不会将打开的文件句柄删除到 POSIX.so
和Fnctl.so
-- 我用 lsof
确定了这一点。这本身就有些令人担忧。我认为在被调用者的包上分配句柄是有意义的。 XSLoader
还掩盖了您可以释放该文件句柄——DynaLoader
中提供的功能。 。
此外,似乎在libc
中/dlfcn.h
我有
dlclose()
The function dlclose() decrements the reference count on the dynamically loaded shared object referred to by handle. If the reference count drops to zero, then the object is unloaded. All shared objects that were automatically loaded when dlopen() was invoked on the object referred to by handle are recursively closed in the same manner.
A successful return from dlclose() does not guarantee that the symbols associated with handle are removed from the caller's address space. In addition to references resulting from explicit dlopen() calls, a shared object may have been implicitly loaded (and reference counted) because of dependencies in other shared objects. Only when all references have been released can the shared object be removed from the address space.
所以我猜这可能是可疑的,DynaLoader::dl_unload_file
正在调用 dlclose
它似乎确实有效。
foreach my $dlref ( @DynaLoader::dl_librefs ) {
print DynaLoader::dl_unload_file($dlref);
}
在我删除了所有加载 DynaLoader
的文件之后和XSLoader
通过执行上述操作,RSS 仍然没有下降。
最佳答案
一般来说,没有。关键的细节是,几乎没有人收缩自己的内存,因为几乎每个人都直接或间接地使用 C 库 malloc
(和 friend )调用来分配内存。并且没有(标准)方法告诉 C 库释放内存(将其发送回操作系统)。 Perl 在这里没有什么不同 - 一旦进行了 malloc 和 free 处理,Perl 所依赖的 C 库就会保留内存以供将来使用,这样如果您需要重用这些内存,不需要昂贵的内核调用(具体来说,brk
),并且可以简单地重用。事实上,这就是您的卸载场景所做的 - 当您返回并在服务器进程的其余部分中重用下一个 2MB 时,您将重新使用内存,而不是调用 brk
,你会更快。
如果您自己接管内存分配所有权并调用 brk
,这是可能的,但这很少值得。让 perl 使用该分配器需要对 perl 进行一些代码更改并重新编译。可能不是您想要做的。
其他选择是要么咬紧牙关,在 fork 任何服务器之前加载 POSIX(这应该将所有内容保留在共享的写时复制内存中,因此对于 5k 服务器仅占用 2MB 内存),或者fork,在子进程中加载 POSIX,完成脏工作,退出子进程,然后在父进程中继续。这对我来说似乎相对较慢。
关于perl - 我可以使用一个模块,然后卸载它以缩小 Optree 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46738256/
免责声明 我不确定我使用的术语是否正确。它可能不是 Optree 造成下面提到的膨胀:它可能是 DynaLoader 加载的符号。没有被释放。 是否可以使用模块,例如 POSIX.pm ,卸载它并减少
我是一名优秀的程序员,十分优秀!