7 Replies Latest reply on Aug 25, 2014 5:43 PM by mpruessmeier

    interrupts gives memory leak

    jacknl

      Hi People,

       

      I have a problem. This week I have installed my Raspberry and the PiFace. All software is the newest (install-date: 20-01-2014)

      After installing, I tested it with: python3 /usr/share/doc/python3-pifacedigitalio/examples/blink.py

      works fine.

       

      When I test this script with Unix command: "top" to see the memory use, the %mem is stable.

       

      When I start (from: /usr/share/doc/python3-pifacedigitalio/examples ):

       

      python ./presslights.py &

      or by

      python3 ./presslights.py &


      the memory use is rising. 

      After 5 to 8 hours the scripts runs "out of memory".


      The only difference with the blink.py script is:

      ====

         pifacedigital = pifacedigitalio.PiFaceDigital()

       

         listener = pifacedigitalio.InputEventListener(chip=pifacedigital)

         for i in range(4):

             listener.register(i, pifacedigitalio.IODIR_ON, switch_pressed)

             listener.register(i, pifacedigitalio.IODIR_OFF, switch_unpressed)

         listener.activate()

      ====


      An other Python-script with interrupts (and I stript it totally) gave the problem with the out of memory problem.

      After this, I tested the input handling, by using polling instead of interrupts.

      With polling the memory is also stable.


      My questions:

      - Do more people have this problem with interrupts (latest Python version)?

      - How can I solve it?


      Best regards from the Netherlands,

      Jack.



        • Re: interrupts gives memory leak
          Eyedoll

          I have not experienced this. I use the "Other" PiFace, the one with the RGB LCD Display (16x2) that has 5 buttons on it.  I have not experienced any memory leaks using any of the scripts or any of modified scripts.

            • Re: interrupts gives memory leak
              jacknl

              Thanks for your input!

               

              I have tested today, and here are the results. First my script:

               

              ==========

              #!/usr/bin/python

               

              import pifacedigitalio

              import time

              import MySQLdb

              from memory_profiler import profile

               

              @profile

              def pulsetodb(pifacedata):

               

                # Open database connection

                db = MySQLdb.connect('localhost', 'web', '*********', 'domotica', charset='utf8', use_unicode=True)

               

                # Prepare SQL query to INSERT a record into the database

                sql = "INSERT INTO raw_piface(timestamp, field, status) VALUES( %s , %s , %s )"

               

                try:

                     # Prepare a cursor object using cursor() method

                     c = db.cursor()

               

                     # Execute the SQL command

                     c.execute(sql, ( pifacedata.timestamp, pifacedata.pin_num, pifacedata.direction ))

               

                     # Commit your changes in the database

                     db.commit()

                     c.close()

               

                except:

                     # Rollback in case there is any error

                     db.rollback()

               

                     # Close database connection

                     db.close()

               

              @profile

              def main():

                pifacedigital = pifacedigitalio.PiFaceDigital()

                listener = pifacedigitalio.InputEventListener(chip=pifacedigital)

               

                # set up listeners for buttons

                listener.register(0, pifacedigitalio.IODIR_FALLING_EDGE, pulsetodb)

               

                # Start listening for events.

                listener.activate()

               

               

              __name__ == '__main__' and main()

              =========

               

              And now the output from the memory_profiler:

               

              =========

               

              pi@domotica ~ $ python -m memory_profiler ./pif_inputs.py

              Filename: ./pif_inputs.py

               

              Line #    Mem usage    Increment   Line Contents

              ================================================

                  49      7.9 MiB      0.0 MiB   @profile

                  50                             def main():

                  51      7.9 MiB      0.1 MiB   pifacedigital = pifacedigitalio.PiFaceDigital()

                  52      8.3 MiB      0.4 MiB   listener = pifacedigitalio.InputEventListener(chip=pifacedigital)

                  53                            

                  54                             # set up listeners for buttons

                  55      8.3 MiB      0.0 MiB   listener.register(0, pifacedigitalio.IODIR_FALLING_EDGE, pulsetodb)

                  56                            

                  57                             # Start listening for events.

                  58      8.3 MiB      0.0 MiB   listener.activate()

               

               

              Filename: ./pif_inputs.py

               

              Line #    Mem usage    Increment   Line Contents

              ================================================

                  21      8.5 MiB      0.0 MiB   @profile

                  22                             def pulsetodb(pifacedata):

                  23                            

                  24                             # Open database connection

                  25      9.4 MiB      0.9 MiB   db = MySQLdb.connect('localhost', 'web', '~?0aU$+I63', 'domotica', charset='utf8', use_unicode=True)

                  26                            

                  27                             # Prepare SQL query to INSERT a record into the database

                  28      9.4 MiB      0.0 MiB   sql = "INSERT INTO raw_piface(timestamp, field, status) VALUES( %s , %s , %s )"

                  29                            

                  30      9.4 MiB      0.0 MiB   try:

                  31                             # Prepare a cursor object using cursor() method

                  32      9.4 MiB      0.0 MiB   c = db.cursor()

                  33                            

                  34                             # Execute the SQL command

                  35      9.4 MiB      0.0 MiB   c.execute(sql, ( pifacedata.timestamp, pifacedata.pin_num, pifacedata.direction ))

                  36                            

                  37                             # Commit your changes in the database

                  38      9.4 MiB      0.0 MiB   db.commit()

                  39      9.4 MiB      0.0 MiB   c.close()

                  40                            

                  41                             except:

                  42                             # Rollback in case there is any error

                  43                             db.rollback()

                  44                            

                  45                             # Close database connection

                  46      9.4 MiB      0.0 MiB   db.close()

               

               

              Filename: ./pif_inputs.py

               

              Line #    Mem usage    Increment   Line Contents

              ================================================

                  21      9.6 MiB      0.0 MiB   @profile

                  22                             def pulsetodb(pifacedata):

                  23                            

                  24                             # Open database connection

                  25      9.6 MiB      0.0 MiB   db = MySQLdb.connect('localhost', 'web', '~?0aU$+I63', 'domotica', charset='utf8', use_unicode=True)

                  26                            

                  27                             # Prepare SQL query to INSERT a record into the database

                  28      9.6 MiB      0.0 MiB   sql = "INSERT INTO raw_piface(timestamp, field, status) VALUES( %s , %s , %s )"

                  29                            

                  30      9.6 MiB      0.0 MiB   try:

                  31                             # Prepare a cursor object using cursor() method

                  32      9.6 MiB      0.0 MiB   c = db.cursor()

                  33                            

                  34                             # Execute the SQL command

                  35      9.6 MiB      0.0 MiB   c.execute(sql, ( pifacedata.timestamp, pifacedata.pin_num, pifacedata.direction ))

                  36                            

                  37                             # Commit your changes in the database

                  38      9.6 MiB      0.0 MiB   db.commit()

                  39      9.6 MiB      0.0 MiB   c.close()

                  40                            

                  41                             except:

                  42                             # Rollback in case there is any error

                  43                             db.rollback()

                  44                            

                  45                             # Close database connection

                  46      9.6 MiB      0.0 MiB   db.close()

               

               

              Filename: ./pif_inputs.py

               

              Line #    Mem usage    Increment   Line Contents

              ================================================

                  21      9.7 MiB      0.0 MiB   @profile

                  22                             def pulsetodb(pifacedata):

                  23                            

                  24                             # Open database connection

                  25      9.7 MiB      0.0 MiB   db = MySQLdb.connect('localhost', 'web', '~?0aU$+I63', 'domotica', charset='utf8', use_unicode=True)

                  26                            

                  27                             # Prepare SQL query to INSERT a record into the database

                  28      9.7 MiB      0.0 MiB   sql = "INSERT INTO raw_piface(timestamp, field, status) VALUES( %s , %s , %s )"

                  29                            

                  30      9.7 MiB      0.0 MiB   try:

                  31                             # Prepare a cursor object using cursor() method

                  32      9.7 MiB      0.0 MiB   c = db.cursor()

                  33                            

                  34                             # Execute the SQL command

                  35      9.7 MiB      0.0 MiB   c.execute(sql, ( pifacedata.timestamp, pifacedata.pin_num, pifacedata.direction ))

                  36                            

                  37                             # Commit your changes in the database

                  38      9.7 MiB      0.0 MiB   db.commit()

                  39      9.7 MiB      0.0 MiB   c.close()

                  40                            

                  41                             except:

                  42                             # Rollback in case there is any error

                  43                             db.rollback()

                  44                            

                  45                             # Close database connection

                  46      9.7 MiB      0.0 MiB   db.close()

               

              =========

              As you can see, the interrupt function is showed once, but the function with SQL is called frequently. Here you can see the memory usage is rising. If the script is running for view hours, it stops on "out of memory". The problem must be in the Interrupt part.

               

              Who can help me?

               

              cheers, Jack.

              • Re: interrupts gives memory leak
                Eyedoll

                Actually, I stand corrected.  I noticed that my Pi becomes unresponsive after about 48 hours of continuous use of the time display script.

              • Re: interrupts gives memory leak
                jkfletch02

                Hi I am experiencing the same issue, the issue seems to lie with the listener as I am pretty sure that I have tried everything else including manual garbage collection and clearing all variables manually after calling the functions. Does anyone have any further insight into this as of yet or possibly a workaround?

                • Re: interrupts gives memory leak
                  mpruessmeier

                  with installed gc i got this on gc.collect()  / and memory is rising -- 

                   

                  [<pifacedigitalio.core.PiFaceDigital object at 0x1cfa510>,

                  <pifacedigitalio.core.PiFaceDigital object at 0x1d6e5f0>,

                  <pifacedigitalio.core.PiFaceDigital object at 0x1d860f0>,

                  <pifacedigitalio.core.PiFaceDigital object at 0x1d95bd0>,

                  <pifacedigitalio.core.PiFaceDigital object at 0x1dae6d0>,

                  <pifacedigitalio.core.PiFaceDigital object at 0x1d55b10>,

                  <pifacedigitalio.core.PiFaceDigital object at 0x1d46030>,

                  <pifacedigitalio.core.PiFaceDigital object at 0x1dc61d0>]