phusick が提供する回答の方が優れていますが、この場合は実際にはオプションではありませんでした。私は次のような解決策を思いつきました:
var dcHandles = [], dsHandles = [], dc = dojo.connect, ds = dojo.subscribe;
dojo.connect = function () {
    var h = dc.apply ( dojo, arguments );
    dcHandles.push ( h );
    return h;
};
dojo.subscribe = function () {
    var h = ds.apply ( dojo, arguments );
    dsHandles.push ( h );
    return h;
};
dojo.subscribe ( "unload", function () {    
    // restore dojo methods
    dojo.connect = dc;
    dojo.subscribe = ds;
    var w, mll;
    mll = dojo._windowUnloaders;
    while (mll.length) {
        ( mll.pop () ) ();
    }
    if ( dijit.registry ) {
        w = dijit.byId ( "topLevelItem1" );
        w && w.destroyRecursive ();
        w = dijit.byId ( "topLevelItem2" );
        w && w.destroyRecursive ();
        // destroy any other wijits
        dijit.registry.forEach ( function ( w ) {
            try
            {
                w.destroyRecursive ();
            }
            catch ( ex )
            {
                $.error ( ex );
            }
        } );
    }
    dojo.forEach ( dcHandles, function ( h ) {
        dojo.disconnect ( h );
    } );
    dojo.forEach ( dsHandles, function ( h ) {
        dojo.unsubscribe ( h );
    } );
   // reset monad-like values
    my.global.values.value1 = null;
    dcHandles = [];
    dsHandles = [];
} );
上記により、多くのコードを変更することなく、すべてが登録解除/破棄/参照解除されるという保証が得られました。