From: Barry S. <ba...@ba...> - 2010-04-09 21:07:18
|
I have reproduced the mem leak on the mac and fedora. I'm looking into the problem. Barry On 7 Apr 2010, at 16:17, Fernando Libonati wrote: > Please see my answer below yours. > >> >> I'll comment inline >>> >>> The base.hxx file is >>> """ >>> #ifndef __BASE__ >>> #define __BASE__ >>> #include "CXX/Objects.hxx" >>> #include "CXX/Extensions.hxx" >>> #include "iostream" >>> #include "string" >> >> Its odd to use "header" and not <header> why do you do this? >> > > Yes, it is a typo ... > >>> >>> #define ENDL "\n"; >> >> Use std::endl as its in the standard. > > For some odd reason, the extension produced with mingw32 as compiler > crashes when std::endl is used. I found that "\n" doesn't, but I don't > know why. If I find some time to review this I will post a comment to > mingw32. > >> >>> >>> class Block: public Py::PythonClass< Block > >>> { >>> Py::Object parent; >>> Py::String name; >>> Py::Int number; >>> public: >>> Block(Py::PythonClassInstance *self, Py::Tuple &args, Py::Dict &kwds) >>> : Py::PythonClass< Block >::PythonClass( self, args, kwds ) >>> { >>> args.verify_length(3); >>> name = args[0]; >>> number = args[1]; >>> parent = args[2]; >>> } >>> >>> virtual ~Block() >>> { >>> } >>> >>> static void init_type(void) >>> { >>> behaviors().name( "Block" ); >>> behaviors().doc( "Clase base para los bloques de simulacion" ); >>> //behaviors().supportSetattr(); >>> behaviors().supportGetattro(); >>> behaviors().supportSetattro(); >>> >>> >>> PYCXX_ADD_NOARGS_METHOD( getFullName, getFullName, "obtener el >>> nombre completo del bloque" ); >>> >>> >>> // Call to make the type ready for use >>> behaviors().readyType(); >>> } >>> >>> //static PyObject* tp_new(PyTypeObject *subtype, PyObject *args, >>> PyObject *kwds) { >>> // return static_cast<PyObject*>(new Block(subtype,args,kwds)); >>> //} >>> //static void tp_dealloc(PyObject *obj) { >>> // Block* k = static_cast<Block*>(obj); >>> // Py::_XDECREF(*(k->parent)); >>> // Py::_XDECREF(*(k->name)); >>> // Py::_XDECREF(*(k->number)); >>> // //delete k; >>> // extension_object_deallocator(obj); >>> //} >> >> PyCXX writes this tp_new and the other necessary functions for you. > > Yes, I've commented those lines (it was a test based on some google > search, but it doesn't work). > >> >>> >>> //Py::Object getFullName( const Py::Tuple& args ) >>> Py::Object getFullName( void ) >>> { >>> std::string r = ""; >>> if( *parent != Py_None ) >> >> You can use parent->isNone(). > > Ok > >> >>> r += >>> Py::String(PyObject_CallMethod(*parent,"getFullName","")).as_std_string( >>> "utf-8" ) + "."; >> >> You are freely mixing Pyhon C API and PyCXX. This means you have to worry >> about reference counting. >> >> Use the newly added callMemberFunction. >> >> Py::String( parent->callMemberFunction( "getFullName" ) ) > > Ok > >> >>> #endif // __BASE__ >>> """ >>> >>> I'm using trunk version of the CXX files. >>> The software works, creates the blocks, chain them, etc, but creating and >>> destroying 1000000 base.Block objects finish with a 44MB memory usage >>> (when 4MB is expected) (the sizeof(Block) is 40 bytes times 1000000 is >>> 40MB !!!) >> >> >>> >>> I've tryed some variations creating Block as a PythonExtension >>> successfully, an the memory doesn't grow with my 1000000 creation/deletion >>> test process (no memory leak). >>> >>> This leads me to thinks that something in the deallocator for >>> new_style_classes isn't working well. >>> What do you think? >> >> >> >>> >>> ---- >>> >>> Also, I've made the test with the simple.cxx module from Demo directory, >>> and the same thing happens (as the object is ligthier you have to >>> create/destroy 10000000, or so, times to see the memory growing). >>> Someone have any clue? >> >> Can you post the python code you used to test simple.cxx which to show the >> memory leak please? > > Ok, see below > >> >> On what python version and operating system are you doing this work? > > Python 2.5.2, Windows XP professional, Mingw32 (gcc 3.4.5 mingw-vista > special r3) > >> >> Barry >> >> > > Attached is the code that shows a memory increase in simple.cxx (with > minor changes to avoid printing a lot when creating and destroying > objects, and with the addition of a Py::String to the old_style_class, > to make it the same content than new_style_class). > > When I run the mytestsimple.py, the python process memory usage starts > at 4072kB, changes to 4080kB after the OLD style class test and then > grows to 28.208kB after the NEW style test (these values are taken > from the Windows Task Manager). > > I also run it with the "MemoryValidator" software, and it shows a > HotSpot before the end (after new style test) > Size Count HotSpot > 271.872 107 1.06%, 271.872 bytes in 107 allocations. > 271.872 107 PyWrapper_New : [{FUNC}PyWrapper_New Line 0] > > 25.165.824 96 98.16%, 25.165.824 bytes in 96 allocations. > 25.165.824 96 PyObject_Dir : [{FUNC}PyObject_Dir Line 0] > >> From that I understand that the memory increase is located or related > to a PyObject_Dir function. I only found one at cxxsupport.cxx, > related to the dir() method of Py::Object, but I can't find where it > is used in the application. > -- > Fernando Libonati > fernando.libonati at gmail.com > <simple.cxx><mytestsimple.py>------------------------------------------------------------------------------ > Download Intel® Parallel Studio Eval > Try the new software tools for yourself. Speed compiling, find bugs > proactively, and fine-tune applications for parallel performance. > See why Intel Parallel Studio got high marks during beta. > http://p.sf.net/sfu/intel-sw-dev_______________________________________________ > CXX-Users mailing list > CXX...@li... > https://lists.sourceforge.net/lists/listinfo/cxx-users |