c - GObject g_type_init 和 g_object_new 耗时数百毫秒

标签 c performance glib gobject

我们在 Apache httpd 模块中使用 Apache Thrift 将来自另一个服务的数据注入(inject)到请求中。除了一些似乎源于 gobject 的奇怪性能问题外,这工作正常。

类型系统和/或第一个对象的初始化通常需要 <1 毫秒,但有时批处理操作系统请求需要更长的时间(例如 >100 毫秒)。

在 child_init-Handler 中,调用 g_type_init() 来初始化类型系统。读取请求时,将使用 g_object_new 创建对象(大约 6)。

对象初始化的时间是用gettimeofday 测量的,以获取用户耗时。它看起来像这样:

VhostResult *result = NULL;
struct timeval  tv1, tv2;
gettimeofday(&tv1, NULL);
result = g_object_new (TYPE_VHOST_RESULT, NULL);
gettimeofday(&tv2, NULL);

该问题只在批量出现。几分钟内所有对象初始化都在 <1 毫秒内,然后在同一秒内有大约 10 个请求需要 500 毫秒来创建第一个对象,所有请求同时完成。

请注意,进程总是在请求后被销毁,所以它总是是一个新的 fork 进程,这意味着没有内存泄漏。

编辑:按照建议,除了挂钟时间外,我还使用 clock() 添加了测量值,它报告测量的代码块为 0。

编辑 2:我查看了 grafana 数据,了解这些批处理缓慢的 inits 弹出并且 iowait 始终很高的时间。有什么东西会因为 iowait 而阻塞进程,或者 iowait 也在测量内存访问吗?

编辑 3:用于计时(cpu 时间)的代码是

  clock_t t = clock();

  result = g_object_newv(TYPE_VHOST_RESULT, 0, NULL);

  t = clock() - t; // stop

  ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "%i %s result init clock %f ms", thepid, r->hostname, ((float)t)/CLOCKS_PER_SEC*1000);

这可能是什么原因?

最佳答案

+1 使用 clock() 或更好的 clock_getttime()。

此外,如果您实例化对象时没有参数,您可以使用以下方法避免可变参数开销:

g_object_newv(TYPE_VHOST_RESULT, 0, NULL);

如果您不时看到尖峰,一种解释可能是内存子系统。 (隐藏的)free() 调用将导致 glibc 不时合并空闲区域。

关于c - GObject g_type_init 和 g_object_new 耗时数百毫秒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34643296/

相关文章:

C do while 循环在检查条件之前重复 2 次

c - scanf (""); 是什么意思?双引号之间只有一个空格?

python - 为什么 Python 排序比 C++ 快

c - g_object_unref : assertion 'G_IS_OBJECT (object)' failed

http - 我可以使用 glib 发出一些可移植的 http GET 请求吗?如何?

c - GLib:通过 UI 传播警告错误

c - 使用哈希函数

c - 为什么更多的线程需要更多的时间来处理?

performance - 加速 Haskell PBKDF2 算法

node.js - 我应该将用户信息放入 JWT token 中,还是只放入用户 ID,然后从数据库中选择信息?