I’m using the phpmailer extension to send my newsletters. Work fine, but around number 300 I get a out of memory error. So I use:
ini_set("memory_limit","256M");
But I think it will only be a matter of time before it will be out of memory again, say 1000 users.
Is it normal that the memory usage build up during sending or is this some kind of memory leak? When you send a newsletters, do you need 1GB memory or more?
I find it hard to debug a ‘memory problem’ not sure how to do this. I did not save the ‘Allowed memory size of … bytes exhausted (tried to allocate … bytes)’ so I have to reproduce it.
Sending starts perfect and work as I want, until about the 300th user, that it crashed with the error above. When the script was running, I can see in my controlpanel that it was eating memory every second . But I guess the mailserver is using memory too?
I can only assume that the object Yii::app()->mailer is continually eating more memory. Instead of that, can you try creating a new mail object each time (within the try block)? Once the reference to the object is changed, it’ll be available for garbage collection rather than lasting for the lifetime of the request.
Nevermind, thanks for thinking along with me. Indeed the emails vary in usernames, content etc.
Ok, so not use the Yii::app()->mailer bust just the PHPMailer (or whatever class) instead you mean?
I presume this is better to give the server some extra time between each send request instead of dumping it all at once to the smtp server. Is this approach useless?
I don’t know how your mailer component is implemented, but it seems like you’re using a single object to represent lots of conceptually distinct objects (messages). If this single object is doing something to update its state on each send, it could be slowly eating more and more memory. This object can’t be garbage collected during the request because there is a constant reference to it in the application class.
It may not be the problem, but it’s where I’d start looking.
But someone else gave me some advice I believe it’s a nice and more stable solution. First get all the emailaddresses and put them in a queue table. Then I run the command an let it send 100 or 200 emails then it ends. The emails in the queue which are send are marked and the next time my cronbjob runs the command, it send the next 200 emails and so on an so fort.
I add some checks and if something happens I write this to my log table. So I keep track of it all and I don’t have to worry that it crash on email nr 1000 or nr 10.000. If it works for 200 emails it will work again and again, right?