Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

More oop weirdness - Cannot clear class

Asked by per isakson on 18 Dec 2012

R2013a doesn't display this problem.

BUG: 893538, Summary, Object array expansion can cause memory leaks. Fixed in R2013a.

.

Original question:

The issue, oop weirdness, reported by Matt J in the Newsgroup a couple of years ago seems to be fixed. It's good news that I fail to reproduce it with R2012a.

Now, I think I found a new testcase for The Mathworks testsuite. It is similar to the case reported by Jim Hokanson in Unable to clear classes. (Comment: Jim Hokanson on 27 Nov 2012 at 18:14)

First, restart Matlab (R2012a), then run the following commands and it is time to restart Matlab again.

>> c3m = C3Main( 1 );
>> clear all, clear classes
>> c3m = C3Main( 4 );
>> clear all, clear classes
Warning: Objects of 'C3Main' class exist.  Cannot ... 
Warning: Objects of 'C3Sub' class exist.  Cannot ...

where

    classdef  C3Main < C3SuperC & C3SuperW
        methods
            function    this = C3Main( N )
                if nargin == 0, return, end 
                c3s = C3Sub( N );
                this.addChild( c3s )
            end
        end
    end
    classdef  C3Sub    < handle
        properties
            Name = 'C3Sub';   
            val
            Parent
        end
        methods
            function this = C3Sub( N )
                if nargin == 0, return, end 
                this( 1, N ) = C3Sub(); 
                for ii = 1 : N
                    this( 1, ii ).val = 17 * ii;
                end
            end
        end
    end
    classdef  C3SuperC < handle
        properties
            Children    = cell(0);
        end
        methods
            function    addChild( this, varargin )
                for ca = varargin
                    child_array = ca{:};
                    for chld = child_array
                        this.Children = cat( 2, this.Children, {chld} );
                        chld.Parent   = this;
                    end
                end
            end
        end
    end

and

    classdef  C3SuperW < hgsetget 
        properties
            Name = 'C3SuperW';
        end
    end

.

The lines

            this( 1, N ) = C3Sub(); 
            for ii = 1 : N
                this( 1, ii ).val = 17 * ii;
            end

in the class C3Sub seems to be the problem - when N = 4. "This only occurs when there are more than 2 children." (Jim Hokanson). Indeed

>> crm = C3Main( 2 );
>> clear all, clear classes
>> crm = C3Main( 3 );
>> clear all, clear classes
Warning: Objects of 'C3Main' class exist.  Cannot clear this ... 
Warning: Objects of 'C3Sub' class exist.  Cannot clear this class ... 

0 Comments

per isakson

Products

No products are associated with this question.

1 Answer

Answer by per isakson on 19 Dec 2012
Edited by per isakson on 19 Dec 2012

The tech support at The Mathworks has reproduce the behavior and reported it to the development team. They also provided a script to delete handle objects. I named it c3cleanup.

c3cleanup is useful if the handles are available. Demo:

>> c3m = C3Main( 4 );
>> c3cleanup
>> clear all, clear classes

so far fine! However,

>> c3handle_lost
>> c3cleanup
>> clear all, clear classes
Warning: Objects of 'C3Sub' class exist.  Cannot clear this class ...
Warning: Objects of 'C3Main' class exist.  Cannot clear this class  
>>  

where

    function    c3handle_lost()
       c3m = C3Main( 4 );       
    end

and

    %% c3cleanup.m
    c3str = who;                                    
    for ii = 1 : length(c3str)                % for each variable... 
        if isa( eval(c3str{ii}), 'handle' )   % if it's a HANDLE object or subclass
            delete( eval(c3str{ii}) )         % delete the object  
            clear( c3str{ii} )                % and clear the handle
        end 
    end 

.

BTW: EVAL is not always evil!

2 Comments

Matt J on 19 Dec 2012

Although, similar to what I found in oop weirdness, I wonder if it would go away if you did

    function    c3handle_lost()
         c3m = C3Main( 4 );       
         clear c3m
    end

or

    function    c3handle_lost()
         c3m = C3Main( 4 );       
         c3cleanup;
    end
per isakson on 21 Dec 2012

In this case Matlab fails to remove the handle objects automatically. They must be cleared a by code (i.e delete(handle)) supplied by the user.

Matlab fails to remove the handle objects when the handle is cleared, whether by clear or when the evaluation of the function is completed.

  • clear c3m in the function does not remove the handle objects from memory.
  • c3cleanup and delete( c3m ) do remove the handle objects from memory.

Demonstration (R2012a):

    >> c3handle_delete()
    >> clear all, clear classes

c3handle_delete leaves no handle objects in memory

    >> c3handle_cleanup()
    >> clear all, clear classes

c3handle_cleanup leaves no handle objects in memory

    >> c3handle_clear()
    >> clear all, clear classes
    Warning: Objects of 'C3Sub' class exist.  Cannot clear this class ...
    Warning: Objects of 'C3Main' class exist.  Cannot clear this class ...
    >> 

c3handle_clear leaves handle objects in memory, which must be removed with a restart of Matlab

The functions are:

    function    c3handle_delete()
         c3m = C3Main( 4 );       
         delete( c3m )
    end
    function    c3handle_cleanup()
         c3m = C3Main( 4 );       
         c3cleanup;
    end

and

    function    c3handle_clear()
         c3m = C3Main( 4 );       
         clear('c3m')
    end
per isakson

Contact us