I am using the version 10.4, but this code is present also in other revision The object created in https://github.com/Geant4/geant4/blob/master/source/processes/hadronic/models/particle_hp/include/G4ParticleHPContAngularPar.hh#L199 Is never deleted... So after a very high number of event the mem leakage became big. I checked in the destructor of the G4Cache<V>::~G4Cache() and enable the #ifdef G4VERBOSE to report if the lock was unavailable, but nothing was written. And also checked that G4CacheReference<V>::Destroy but logic is not very clear to me at the moment if the whole cached is deleted , or... just a single element (I see no iteration) I will try and check more code to see If I am able to provide a fix, but for now I can only provide a stack trace of the leakage 30K iteration Direct leak of 310080 byte(s) in 6460 object(s) allocated from: #0 0x7f9b7994bcb0 in operator new(unsigned long) (/usr/lib64/libasan.so.4+0xddcb0) #1 0x7f9b77418f5e in G4ParticleHPContAngularPar::cacheInit() /home/ryzen2/geant4/source/processes/hadronic/models/particle_hp/include/G4ParticleHPContAngularPar.hh:199 #2 0x7f9b77412bc7 in G4ParticleHPContAngularPar::G4ParticleHPContAngularPar(G4ParticleDefinition*) /home/ryzen2/geant4/source/processes/hadronic/models/particle_hp/src/G4ParticleHPContAngularPar.cc:63 #3 0x7f9b7741c562 in G4ParticleHPContEnergyAngular::Sample(double, double, double) /home/ryzen2/geant4/source/processes/hadronic/models/particle_hp/src/G4ParticleHPContEnergyAngular.cc:84 #4 0x7f9b773fab81 in G4ParticleHPProduct::Sample(double, int) /home/ryzen2/geant4/source/processes/hadronic/models/particle_hp/src/G4ParticleHPProduct.cc:124 #5 0x7f9b774291b7 in G4ParticleHPEnAngCorrelation::Sample(double) /home/ryzen2/geant4/source/processes/hadronic/models/particle_hp/src/G4ParticleHPEnAngCorrelation.cc:195 #6 0x7f9b7740ad6f in G4ParticleHPCaptureFS::ApplyYourself(G4HadProjectile const&) /home/ryzen2/geant4/source/processes/hadronic/models/particle_hp/src/G4ParticleHPCaptureFS.cc:90 #7 0x7f9b77410c2f in G4ParticleHPChannel::ApplyYourself(G4HadProjectile const&, int) /home/ryzen2/geant4/source/processes/hadronic/models/particle_hp/src/G4ParticleHPChannel.cc:308 #8 0x7f9b77406c3d in G4ParticleHPCapture::ApplyYourself(G4HadProjectile const&, G4Nucleus&) /home/ryzen2/geant4/source/processes/hadronic/models/particle_hp/src/G4ParticleHPCapture.cc:141 #9 0x7f9b76fb75d9 in G4HadronicProcess::PostStepDoIt(G4Track const&, G4Step const&) /home/ryzen2/geant4/source/processes/hadronic/management/src/G4HadronicProcess.cc:344 #10 0x7f9b784b36c4 in G4SteppingManager::InvokePSDIP(unsigned long) /home/ryzen2/geant4/source/tracking/src/G4SteppingManager2.cc:562 #11 0x7f9b784b354e in G4SteppingManager::InvokePostStepDoItProcs() /home/ryzen2/geant4/source/tracking/src/G4SteppingManager2.cc:534 If instead I run with less iteration (10K) is similar with Direct leak of 106512 byte(s) in 2219 object(s) allocated from: #0 0x7f011051fcb0 in operator new(unsigned long) (/usr/lib64/libasan.so.4+0xddcb0) #1 0x7f010dfecf5e in G4ParticleHPContAngularPar::cacheInit() /home/ryzen2/geant4/source/processes/hadronic/models/particle_hp/include/G4ParticleHPContAngularPar.hh:199 #2 0x7f010dfe6bc7 in G4ParticleHPContAngularPar::G4ParticleHPContAngularPar(G4ParticleDefinition*) /home/ryzen2/geant4/source/processes/hadronic/models/particle_hp/src/G4ParticleHPContAngularPar.cc:63 #3 0x7f010dff0562 in G4ParticleHPContEnergyAngular::Sample(double, double, double) /home/ryzen2/geant4/source/processes/hadronic/models/particle_hp/src/G4ParticleHPContEnergyAngular.cc:84 #4 0x7f010dfceb81 in G4ParticleHPProduct::Sample(double, int) /home/ryzen2/geant4/source/processes/hadronic/models/particle_hp/src/G4ParticleHPProduct.cc:124 #5 0x7f010dffd1b7 in G4ParticleHPEnAngCorrelation::Sample(double) /home/ryzen2/geant4/source/processes/hadronic/models/particle_hp/src/G4ParticleHPEnAngCorrelation.cc:195 #6 0x7f010dfded6f in G4ParticleHPCaptureFS::ApplyYourself(G4HadProjectile const&) /home/ryzen2/geant4/source/processes/hadronic/models/particle_hp/src/G4ParticleHPCaptureFS.cc:90 #7 0x7f010dfe4c2f in G4ParticleHPChannel::ApplyYourself(G4HadProjectile const&, int) /home/ryzen2/geant4/source/processes/hadronic/models/particle_hp/src/G4ParticleHPChannel.cc:308 #8 0x7f010dfdac3d in G4ParticleHPCapture::ApplyYourself(G4HadProjectile const&, G4Nucleus&) /home/ryzen2/geant4/source/processes/hadronic/models/particle_hp/src/G4ParticleHPCapture.cc:141 #9 0x7f010db8b5d9 in G4HadronicProcess::PostStepDoIt(G4Track const&, G4Step const&) /home/ryzen2/geant4/source/processes/hadronic/management/src/G4HadronicProcess.cc:344 #10 0x7f010f0876c4 in G4SteppingManager::InvokePSDIP(unsigned long) /home/ryzen2/geant4/source/tracking/src/G4SteppingManager2.cc:562 #11 0x7f010f08754e in G4SteppingManager::InvokePostStepDoItProcs() /home/ryzen2/geant4/source/tracking/src/G4SteppingManager2.cc:534
So yes I can confirm is a bug somewhere in the actual logic, the comment in the destructor here is quite clear https://github.com/Geant4/geant4/blob/6aa23be5171b125c3363b5a4cfa00a57e524598b/source/global/management/include/G4CacheDetails.hh#L252 // Ownership is for client // delete (*cache)[id]; So during the destruction phase the vector is cleaned, but NOT the object inside... which are responsability of the owner of the cache. Now I will check if is ok to delete during the destructor this cache, or if this value has been passed around.
I am now 99% sure that yes is possible to clean element in the cache in the destructor of G4ParticleHPContAngularPar, the content is not passed anywhere after the end of life of the obj. I will now mod my local copy, and let run a quite long simulation.
Basically the problem arises from https://github.com/Geant4/geant4/blob/6aa23be5171b125c3363b5a4cfa00a57e524598b/source/global/management/include/G4CacheDetails.hh#L227 In case that the value to be placed in the Cache is a ptr, a temporary object is created, stored and than LOST because later will be overwritten... If instead the object is not a ptr, the temp one is created, and than later properly destroyed when is overwritten. I also checked adding https://en.cppreference.com/w/cpp/types/is_pointer static_assert (std::is_pointer<V>::value, "do not use with PTR"); To see where else a ptr is used and is in several place. Proposed fix is to template<class V> void G4Cache<V>::Put( const V& val ) const { if constexpr(std::is_pointer<V>::value) { delete GetCache(); } GetCache() = val; } But sadly is cached a ptr of G4VelocityTable which is a singleton, so ... no public destructor... So I think we just have to change the leaking class to not store a ptr...
Hi, Roy Thank you for reporting a bug with detailed investigation. And sorry for my late response. I have a question on your report. In the G4ParticleHPContAngularPar class, toBeCached struct is defined for G4Cache template. http://www-geant4.kek.jp/lxr/source/processes/hadronic/models/particle_hp/include/G4ParticleHPContAngularPar.hh#L49 class It contains three G4double and two pointers to G4ReactionProduct. http://www-geant4.kek.jp/lxr/source/processes/hadronic/util/include/G4ReactionProduct.hh You said " But sadly is cached a ptr of G4VelocityTable which is a singleton, so ... no public destructor... " G4VelocityTable is defined as a static member of G4Track. But, G4ReactionProduct has the pointer to G4ParticleDefinition not to G4Track. Could you explain how G4VelocityTable is related to this problem ? And I'd explain memory allocation of a singleton object. It is allocated automatically at the beginning of running the program, and is deleted at the end of running the program. Its constructor and destructor are invoked automatically and are not called by other classes. So, no public constructor and destructor are provided. Thank you and Cheers, Hisaya
Hy Hisaya. The problem with the singleton is that the proposed fix with the "static if" can not be applied, because ... it can not call the destructor for this object! So ... is not leaking the Singleton, but is blocking the cache to ... work with just a single small fix...
I forward this problem to Makoto, who is responsible for G4Cache
Problem is already fixed in the development version and will be included in next releases. *** This problem has been marked as a duplicate of problem 2026 ***