This story is inspired by the Gameroom Junkies call to action on Facebook this morning. So, here is the story I shared with them.
My fondest Christmas gaming memory is the morning a computer desk and Atari 520 ST mysteriously appeared in our living room overnight!
It was our 2nd computer, we had gotten a Vic 20 a couple of Christmases before. While I have vague memories of typing seemingly random symbols to run games off of a cassette tape. I remember very clearly sitting in a chair next to my dad on Christmas morning and playing King’s Quest II together.
This was my first social gaming experience. My mom, dad, sister, and I would all crowd around that 12 inch color monitor. My dad would control King Graham while we all suggested what we should do next. I remember being really startled the first time that witch from the cave appeared. That spooky tune is stuck in my head to this day!
Audio Source: VGMPF
Here is a quick update summarizing the changes I have made over the past few days. I am convinced I have removed 99% of the memory leaks. The memory on my Raspberry Pi stayed pretty stable yesterday.
The summary of what has changed is this:
import gc was added to garagemonitor.py (the Python Garbage Collector).
gc.collect() was added to the end of my main loop (so its runs on each cycle and tries to free any orphaned variables/objects).
keep_garage_monitor_active.sh bash script was created to researt the garagemonitor service when the script is no longer in the process list (for some reason it has terminated a couple of times on me, I am not sure why).
- The Status web page no longer reload the entire page every 10 seconds. Instead, it now uses AJAX to query the Web Service every 5 seconds. It now only reloads the page when the status has actually changed. This saves workload and bandwidth for the server, and moves more of the work to the client’s browser.
- The Status web page background grows bright then returns to the normal color to indicate when the status has been updated.
I may even rework the status webpage all together again so it never reloads the entire page again. I am looking at the jQuery Mobile framework right now.
As always a stable version of my code is avilable at Github.
I have added a wish list item to my My Raspberry Pi Garage Monitor. I added the ability for users to be able to issue requests from buttons on the Status Page. The first button issues a “Status Refresh” request.
Action Request Web Service
For safety I decided not to make the Pi accessible to the Internet, so I setup a second web service. The button submits a form which stores the request in a file. A web service which reads that file is queried by the Raspberry Pi every so often. Right now I have garagemonitor.py setup to query the service every 60 seconds.
I may add the ability to close the garage door on the Open Status Page. However, there are some issues to consider.
- We do not want the web service to be able to open the door. (For safety reasons.)
- The door could be closed remotely while someone is backing out of the garage. (For example, my wife checks the status at work and closes the door while I am backing my car out.)
Does anyone have any other ideas?
Note: this is part 3 of a series. You can see all of the articles I have written on my Garage Monitor here.
A Possible Solution
OK, so after going down the route of debugging and tracing, I realized I had no idea what I was looking for. So I started thinking about what I should be doing to cleanup. I realized that I wasn’t freeing the memory of the objects that I was using in the functions. So, I started trying to figure out how to do that.
So after making some modifications, I have been randomly taking readings by running the free command. Over the last 2-3 hours the free memory is staying quite stable. In fact for a couple of the readings the free memory actually goes up: 349816, 349824, 349576, 349700, 349584, 349576, 349584!
Update: I may have found a solution. Read about it in Garage Monitor Memory Leak: Part 3
Note: While this was an interesting exercise, I don’t understand the results so I cannot use them to find the issues at this time. I think my next step will look up some Python Best Practices. I have already found an interesting discussion on Stack Overflow.
In an effort to trace the memory leak, I discovered an article. In the article Marek Majkowski describes using the Python Debugger (PDB), and a garbage collection library. His article also describes the use of Python Object Graphs, an open source library written by Marius Gedminas.