-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Memory not being reclaimed #62
Comments
ok so let me reiterate what you've got here so i make sure i understand correctly. you've initialized the there is a place in the prime_server api to do cleanup after each request. you'll notice you can attach a im not sure if this will solve your issue though because i dont know how the internals of |
It seems that rstar_index class which uses internally Libspatialindex has some issue. It allocates some variables on heap and never frees them(except when process ends). However i don´t even know how to debug that since there is no memory leak. I have tried to look on /proc/pid/maps, but that doesn´t say which function makes the allocation. Do you have any idea on how to solve this kind of issue? |
I would guess that this library caches that information on purpose (ie its not a leak) so as to accelerate subsequent requests. indeed, valhalla, the routing software that i use with prime_server also does this. i am not familiar with libspatialindex but i would fish around in the docs for clues on what it keeps in memory. to me it looks like your test program that doesnt use prime_server should show similar memory usage patterns, that is use a lot while the program is running and then release it only when the program finishes. it seems to me the issue with memory use is probably not at all related to prime_server. at any rate if you do find a way to tell the libspatialindex api to deallocate its cache you can do so in the |
I have investigated the problem deeper and it is not necessarily connected with the library. The issue is connected with the threads inside prime_server. You implemented cleanup function for each thread,but since no thread ever dies, the locally allocated variables which went out of scope, all that memory is not released back to OS. So i really wonder how you don´t have issues on your server when you run a lot of requests. That memory is never released back to OS and the process still occupies it. Is there some other way to release the freed memory back to OS other than forking a new process inside each thread that does the processing? |
the can you try something else just for fun? could you write your worker function as a free function that takes those large memory objects by reference and then pass pass those objects to the method as |
The problem is not with the large memory objects. I have tried using apache benchmark for 10000 requests and i commented out all my functions(find_nearest, etc.) and send back just hello world. After all those requests, the memory raised and it was never freed. This is the problem that our process can't tell OS that it has freed memory, because the threads are part of the process. You can easily replicate this issue yourself on prime_echod example.
Just server running - 3.6 MB as showed in gnome monitor which outputs physical resident set without mapped files. |
now that is something i can look into, ill have a quick go with valgrind! |
interesting, ive confirmed that |
Okay i did some digging, this issue is connected with the memory fragmentation. To me the problem only appears when i am trying to use some dynamically allocated containers like vector or string inside the classes. I have found an interesting article here http://natsys-lab.blogspot.sk/2015/09/fast-memory-pool-allocators-boost-nginx.html. I have tried to use solution provided by Facebook, namely library folly which contains Arena.h pool implementation. When using pool for instance for vector memory indeed gets released,but this only works for types with fixed length - ie. uint, int, double,... I can also imagine using it for strings, you get the string length and ask the allocator, but the real problem is how would i create class which uses this pool.
Problem is that the problem still persists with 100k points inserted. All of the memory is just not freed back to OS. |
sorry i have been absent a while. i'm going to keep this issue open until i find time to properly spend looking into it. seems like something inherent to multithreading that i've not come across before or was not aware of. |
I don' t know whether it is a problem with the library itself,but it seems it is kind of expected behavior of libc library. Even some other guy on the Internet noticed this https://news.ycombinator.com/item?id=14275805. I will try to compile my application with libc++(https://libcxx.llvm.org/) and see if that makes any difference. I was thinking about it for a longer period of time,but if the problem was memory fragmentation only, then we should be only very slowly taking up RAM from the OS,because we should be able to fill up the freed pages. But apparently this is not happening, application is still requesting new pages even if it could re-use some of them. I was trying those funny environmental variables and for a while i thought it fixed the issue in the longer runs of server, but now i am not even sure, because it was behaving similarly without the env variable. |
i dont know if this is an option for you, but when we run this in production we dont run it as a single process, for the sake of fault tolerance. each worker is its own process. so we'll run a |
oh i should mention when i say processes i mean each is its own stand alone program, no forks or any nonsense like that |
i've just merged a pr by @LaGrunge who found that were free'ing inside of an assert, which means only debug builds were actually free'ing... this sounds very much related to this thread so if anyone has any interested in checking their applications again it'd be great to hear from you! reference #85 |
Hello,
i am running a daemon process which parses request and
To each of these layers i send pointers which are captured inside lambda work function for each layer. I have written a check program which uses all functions that i am using inside daemon and ran memcheck on that, there are no memory leaks . However any variables that were used inside the work function still claim memory even after the thread ends. I am checking memory usage through Gnome System Info.
For instance when function find_trip does some heavy processing and all variables inside (R-tree, hash map) take 300 MB space,these variables are not freed even if they were not allocated through new. They somehow keep to live inside the process and the memory usage is never lower even if i run less resource intensive request afterwards.
I am attaching my daemon code below. Can you please take a look and help me figure out what am i doing wrong?
The text was updated successfully, but these errors were encountered: