简体   繁体   English

在Perl中,在属性中保留对Catalyst的$ c的引用会导致内存泄漏吗?

[英]In Perl, would keeping a reference to Catalyst's $c in an attribute cause a memory leak?

I started off writing some Perl code using Catalyst that looked like this: 我开始使用Catalyst编写一些Perl代码,如下所示:

package My::Controller;
extends 'Catalyst::Controller';

sub handler :Path :Args(0) :Location( some/url )
    my ($self, $c) = @_;

    $self->do_something_with_arguments($c);
    $self->make_a_decision($c);
    $self->another_method($c);
}

Then I thought . 然后我想。 o O ( Why pass $c around all the time? ), and I changed to this: o(为什么一直传递$ c?),我改为:

package My::Controller;
extends 'Catalyst::Controller';

has c => (is => "rw", isa => "Catalyst");

sub handler :Path :Args(0) :Location( some/url )
    my ($self, $c) = @_;
    $self->c($c);

    $self->do_something_with_arguments;
    $self->make_a_decision;
    $self->another_method;
}

There is only one entry point to the handler, so $self->c will always be set correctly. 处理程序只有一个入口点,因此$ self-> c将始终正确设置。

My colleagues said that if this was how Catalyst was meant to be used then, well, everyone would use it like that. 我的同事说,如果这就是Catalyst的意思,那么,每个人都会这样使用它。 They were worried that doing it this way would cause a memory leak because the reference to $c would persist after the request was over. 他们担心这样做会导致内存泄漏,因为在请求结束后对$ c的引用会持续存在。 Is that true? 真的吗?

This isn't a "memory leak" in the exact sense that most people think of, since it won't result in unbounded memory growth, but yes, you're keeping a request context around longer than its ordinary lifetime. 这并不是大多数人想到的“内存泄漏”,因为它不会导致无限制的内存增长,但是,是的,您将请求上下文保持的时间长于其普通生命周期。 It'll be freed the next time you make a request that sets $self->c to something else, but not any sooner. 它会在您下次发出将$self->c为其他内容的请求时释放,但不会更快。 More importantly though, it's pretty much just wrong design. 更重要的是,它几乎只是错误的设计。 Either continue passing the context as an argument; 要么继续传递上下文作为参数; or turn your controller methods into private actions and call them with ->forward (which passes the context automatically); 或者将您的控制器方法转换为私有操作,并使用->forward (自动传递上下文)调用它们; or move things into the model if appropriate, and have the model ACCEPT_CONTEXT . 或者在适当的情况下将事物移入模型中,并使用模型ACCEPT_CONTEXT

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM