Memory leak of 36 bytes from 1 block allocated in nsPrefServiceConstructor (nsPrefService)

RESOLVED WORKSFORME

Status

()

Core
Preferences: Backend
--
major
RESOLVED WORKSFORME
16 years ago
15 years ago

People

(Reporter: stephend@netscape.com (gone - use stephen.donner@gmail.com instead), Assigned: Brian Nesse (gone))

Tracking

({memory-leak})

Trunk
mozilla1.2alpha
x86
Windows 2000
memory-leak
Points:
---

Firefox Tracking Flags

(Not tracked)

Details

Build ID: Latest Win32 trunk on Windows 2000 running under Purify.

Summary: Memory leak of 36 bytes from 1 block allocated in nsPrefServiceConstructor

Steps to Reproduce:

1.  Launch mozilla -compose (HTML compose).
2.  Autocomplete an address, then arrow to it in the drop-down list.
3.  Type 'test' in the subject and 'test' in the body.
4.  Hit Send.

[W] MLK: Memory leak of 36 bytes from 1 block allocated in nsPrefServiceConstructor
    Distribution of leaked blocks
    Allocation location
    new(UINT)      [MSVCRT.DLL]
    nsPrefServiceConstructor [nsPrefsFactory.cpp:48]
    extern NS_IMETHODIMP nsPrefConstructor(nsISupports *aOuter, REFNSIID aIID,
void **aResult);
    
    
 => NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrefService, Init)
    NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrefLocalizedString, Init)
    
    // The list of components we register
    nsGenericFactory::CreateInstance(nsISupports *,nsID const&,void * *)
[nsGenericFactory.cpp:74]
                                                   REFNSIID aIID, void **aResult)
    {
        if (mInfo->mConstructor) {
 =>         return mInfo->mConstructor(aOuter, aIID, aResult);
        }
    
        return NS_ERROR_FACTORY_NOT_REGISTERED;
    nsComponentManagerImpl::CreateInstanceByContractID(char const*,nsISupports
*,nsID const&,void * *) [nsComponentManager.cpp:1658]
        nsresult res = FindFactory(aContractID, &factory);
        if (NS_SUCCEEDED(res))
        {
 =>         res = factory->CreateInstance(aDelegate, aIID, aResult);
            NS_RELEASE(factory);
        }
        else
    nsComponentManagerImpl::GetServiceByContractID(char const*,nsID const&,void
* *) [nsComponentManager.cpp:2023]
        // the service manager:
        mon.Exit();
    
 =>     rv = CreateInstanceByContractID(aContractID, NULL, aIID,
getter_AddRefs(service));
    
        mon.Enter();
    
    nsGetServiceByContractID::()(nsID const&,void * *)const
[nsComponentManager.cpp:242]
            nsCOMPtr<nsIServiceManager> mgr;
            NS_GetServiceManager(getter_AddRefs(mgr));
            if (mgr)
 =>             status = mgr->GetServiceByContractID(mContractID, aIID,
(void**)aInstancePtr);
        }
    
        if ( NS_FAILED(status) )
    nsCOMPtr_base::assign_from_helper(nsCOMPtr_helper const&,nsID const&)
[nsCOMPtr.cpp:80]
    nsCOMPtr_base::assign_from_helper( const nsCOMPtr_helper& helper, const
nsIID& iid )
        {
            nsISupports* newRawPtr;
 =>         if ( NS_FAILED( helper(iid, NS_REINTERPRET_CAST(void**, &newRawPtr)) ) )
                newRawPtr = 0;
        assign_assuming_AddRef(newRawPtr);
        }
    nsMapiSupport::Observe(nsISupports *,char const*,WORD const*)
[msgMapiSupport.cpp:115]
        rv = observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
PR_FALSE);
            if (NS_FAILED(rv))  return rv;
        
     =>      nsCOMPtr<nsIPrefService> prefs =
do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
            if (NS_FAILED(rv))  return rv;
        
            nsCOMPtr<nsIPrefBranchInternal> prefInternal =
do_QueryInterface(prefs, &rv);
    nsAppStartupNotifier::Observe(nsISupports *,char const*,WORD const*)
[nsAppStartupNotifier.cpp:104]
                            startupObserver = do_CreateInstance(contractId, &rv);
        
                        if (NS_SUCCEEDED(rv)) {
     =>                     rv = startupObserver->Observe(nsnull, aTopic, nsnull);
        
                            // mainly for debugging if you want to know if your
observer worked.
                            NS_ASSERTION(NS_SUCCEEDED(rv), "Startup Observer
failed!\n");
    main1          [nsAppRunner.cpp:1138]
    main           [nsAppRunner.cpp:1594]
    WinMain        [nsAppRunner.cpp:1612]
    WinMainCRTStartup [crtexew.obj]
Keywords: mailtrack, mlk, nsbeta1

Comment 1

16 years ago
I'll bet this is nsPrefService, and if so this is probably causing bug 118893,
I'd recommend marking that a dupe of this
Summary: Memory leak of 36 bytes from 1 block allocated in nsPrefServiceConstructor → Memory leak of 36 bytes from 1 block allocated in nsPrefServiceConstructor (nsPrefService)
QA Contact: sairuh → jrgm
(Assignee)

Comment 2

16 years ago
The nsPrefService object is 36 bytes in size. The nsPrefBranch object is 68
bytes in size. When you create the service, it creates a branch and keeps a
cached copy of it for the life of the service. The service stays alive for the
life of the application.

I guess I don't see how this (or bug 118893) is a memory leak...

Comment 3

16 years ago
we should not leak service objects, even if they are around for the life of the
application - it adds noise to purify/etc and obscures true leaks... other
services are not leaked so this is something specific to nsPrefService or its
consumers. someone may be holding onto a reference to the pref service.. 

on a related note, I was thinking that we might want to roll the root
nsPrefBranch into the nsPrefService object, to avoid an extra allocation:
i.e. instead of

nsPrefService : public nsIPrefService {

  nsCOMPtr<nsIPrefBranch> mRootBranch;

}

we have
nsPrefservice : public nsIPrefService {

  nsPrefBranch mRootBranch;
}

then these two objects will be allocated in the same space, and we save the 4
bytes of pointer used to allocate mRootBranch... and that will fix the other bug
because it will look like just this object leaks :)
(Assignee)

Comment 4

16 years ago
Sure, we can do that, but if/when the caching of non-root level branches is
added (bug 113635) it will reappear.

As far as shutting down the PrefService, I would expect the service manager
(component manager?) to cause the final release. Stepping through the shutdown
process I don't see this happen (though there are still 22 ref's held on the
component manager when it is killed). I assume that something akin to
tracerefcount is the only way to track down the consumer still holding references?
(Assignee)

Comment 5

16 years ago
*** Bug 118893 has been marked as a duplicate of this bug. ***
(Assignee)

Updated

16 years ago
Target Milestone: --- → mozilla1.0

Comment 6

16 years ago
nsbeta1- per ADT/Embed triage.
Keywords: nsbeta1 → nsbeta1-
Target Milestone: mozilla1.0 → mozilla1.2
no longer seeing this, win2k, purify, trunk...
Status: NEW → RESOLVED
Last Resolved: 15 years ago
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.