我目前正在尝试增强兽库,现在对它的内存占用感到非常惊讶。我发现通过使用三种不同的响应类型(字符串,文件,动态),程序大小可以增长到6Mb。
为了更深入地了解原因,我从库中获取了小型服务器示例,并将其简化为以下步骤:
class http_connection : public std::enable_shared_from_this<http_connection>
{
public:
http_connection(tcp::socket socket) : socket_(std::move(socket)) { }
void start() {
read_request();
}
private:
tcp::socket socket_;
beast::flat_buffer buffer_{8192};
http::request<http::dynamic_body> request_;
void read_request() {
auto self = shared_from_this();
http::async_read(
socket_, buffer_, request_,
[self](beast::error_code ec,
std::size_t bytes_transferred)
{
self->write_response(std::make_shared<http::response<http::dynamic_body>>());
self->write_response(std::make_shared<http::response<http::file_body>>());
self->write_response(std::make_shared<http::response<http::string_body>>(), true);
});
}
template <class T>
void write_response(std::shared_ptr<T> response, bool dostop=false) {
auto self = shared_from_this();
http::async_write(
socket_,
*response,
[self,response,dostop](beast::error_code ec, std::size_t)
{
if (dostop)
self->socket_.shutdown(tcp::socket::shutdown_send, ec);
});
}
};
当我注释掉三行self-> write_response行并编译程序并在结果上执行size命令时,我得到:
text data bss dec hex filename
343474 1680 7408 352562 56132 small
当我删除第一次写的评论时,我得到:
864740 1714 7408 873862 d5586 small
text data bss dec hex filename
删除所有评论后,最终大小将变为:
text data bss dec hex filename
1333510 1730 7408 1342648 147cb8 small
4,8M Feb 16 22:13 small*
现在的问题是:
我做错什么了吗?
有没有办法减小尺寸?
更新
真实的process_request看起来像:
void process_request() {
auto it = router.find(request.method(), request.target());
if (it != router.end()) {
auto response = it->getHandler()(doc_root_, request);
if (boost::apply_visitor(dsa::type::handler(), response) == TypeCode::dynamic_r) {
auto r = boost::get<std::shared_ptr<dynamic_response>>(response);
send(r);
return;
}
if (boost::apply_visitor(dsa::type::handler(), response) == TypeCode::file_r) {
auto r = boost::get<std::shared_ptr<file_response>>(response);
send(r);
return;
}
if (boost::apply_visitor(dsa::type::handler(), response) == TypeCode::string_r) {
auto r = boost::get<std::shared_ptr<string_response>>(response);
send(r);
return;
}
}
send(boost::get<std::shared_ptr<string_response>>(send_bad_response(
http::status::bad_request,
"Invalid request-method '" + std::string(req.method_string()) + "'\r\n")));
}
预先感谢
答案 0 :(得分:0)
如果您实际上并没有在泄漏内存,那么没有任何问题。系统分配的任何内存都将重新用于您的程序或最终归还给您。由于虚拟内存系统的存在,很难测量程序的真实内存使用情况,尤其是在Linux下。除非您看到实际的泄漏或实际问题,否则我将忽略那些内存报告,而只是继续实施您的业务逻辑。 Beast本身不包含内存泄漏(在valgrind,asan和ubsan下在Travis和Appveyor上进行了广泛的每次提交测试)。
答案 1 :(得分:0)
尝试使用malloc_trim(0)
的析构函数,例如http_connection
。
来自man
:
malloc_trim-从堆顶部释放可用内存。
malloc_trim()函数尝试释放堆顶部的可用内存(通过使用适当的参数调用sbrk(2))。
pad参数指定堆顶部未修剪的可用空间量。
如果此参数为0,则仅在堆的顶部(即一页或更少)保持最小的内存量。非零参数可用于在堆顶部保留一些尾随空间,以便将来进行分配时不必扩展堆。 sbrk(2)。