On which operating system are you on and which GH version are you using?
Normally graphHopper.close should release all resources and give also access of the underlying files back to the OS. The problem might be that e.g. if you are using Android the memory mapping is on per default and releasing resources cannot be forced, one can give the OS only a hint and hope the best when using Java APIs only
Can you try the following:
graphHopper.close()
for loop from 1 to 10 {
System.gc()
sleep 1 second
try {
graphHopper.clean()
break
} catch(IOException ex) {
continue
}
}
Also some kind of a native cleanup (which requires changes to GH itself) could help, not sure.
Oh, sorry.
I am using graphhopper 0.6 on Android.
Well, thank you for quick response and advice.
The problem is that I have to periodically update graphHopper’s files on the device. When update is ready, user can see specifical button on the screen.
But graphHopper already could be loaded here (user used some routes and came back on activity from stack).
So, I think that the best way is here - hide update button if gh was loaded, because we really can’t release resources (tried your advice).
What is your opinion in this case?
Thanks for describing your use case. That is indeed ugly and we have to fix it somehow or at least try to find a good solution.
What if you download the update to a new folder, then close the old GraphHopper instance and create a new one pointing to a different folder?
And a new start of your application could then remove the old, now no longer used folder. To avoid the restart you could try to remove the old folder after you have loaded the new GraphHopper instance as the garbage collector could be forced to clean up a bit more.
Good option, but more expensive on storage memory.
I use at least 12 different folders for graphHopper in application (depends on city).
User can download all of them.
And update is coming at the same time for all of them. That’s why I can’t afford it.
But it’s not a big deal, I’m more inclined to hide this update button, if user ignored it at 1st time.
Thanks, this is good to know! And it indicates that if you force the garbage collector to do his work it will release the file resources. Maybe you can try to allocate some memory in the loop to force the GC without duplicating storage?
graphHopper.close()
for loop from 1 to 10 {
temp_store = new int[5 * 1024 * 1024]
// or instead temporarily load a different city here?
System.gc()
sleep 1 second
try {
graphHopper.clean()
break
} catch(IOException ex) {
continue
}
}
I meant: if the graphhopper.load succeed then you can delete the old folder afterwards, right? So why not load city B if you need to delete folder of city A? (memory mapping should be relative cheap)
Yes. (Maybe it is more secure to do this in a loop)
But you said you cannot effort the extra disc space? And to avoid the extra disc space you could try to load a different city B first, remove the old city A, download city A and do graphhopper.load city A and then throw away graphhHopper with city B.
Yes, in this case I can do it.
To be honest, I think that 95% of users will use only one city.
And I really started to think about your advice in creating new folder for update in this situation.
Or rename old gh files (if I can), download new files, initialize new graphHopper object and remove old files.
java.io.IOException: EBUSY (Device or resource busy)
Sorry, I can’t get full trace right now. But I remember the reference on “edges”, which as we know is using by graphHopper.
Three other devices made it without exception.
I think, this could be because of different OS version or smth like that.