I have memory leak in my project and I wonder how garbage collector working in Flash Media Server.
I have 2 questions:
Will FMS release objects from memory that have cycle references. For example when object A is has ref to Object B and vise versa.
Why FMS still consumes memory after application unloaded by idle timeout. For example there were no users connected then fms unloaded app after 20 minutes. Memory usage left at the same level (for a long period of time).
In general I miss some best practices of writing FMS code.
FMS 3.5.1 on WinXP
Related
So I already asked this question on the unity forums but that didn't help me a lot :/. Today I decided to give my game a try with friends so basically I created a server so other clients/friends could connect to it. After about 20 minutes of playing my game crashed and I quickly checked task manager and my game was using about 3.5 GB of RAM! PHOTO HERE When I looked at the log it said something like this:
Unity Player [version: Unity 4.6.1f1_d1db7a1b5196]
mono.dll caused an Access Violation (0xc0000005)
in module mono.dll at 0023:101071a1.
Error occurred at 2016-07-04_163050.
C:\Users\Cooler Master\Desktop\TL\TL.exe, run by Cooler Master.
77% memory in use.
0 MB physical memory [1814 MB free].
0 MB paging file [1039 MB free].
0 MB user address space [68 MB free].
Write to location 00000000 caused an access violation.
So in my game there is something that keeps eating my RAM. It takes about 3MB per second of ram when the game is running. I found some information on internet about Resources.UnloadUnusedAssets but I don't know how to write a script like that! I knew how to write in c# but only the easy scripts like GUI,Newtorkinf,Physics etc.. Also I downloaded unity pro from kickasstorrent only to see profiler window but that didn't help me at all
Thank very much for any reply !
Also if you want to check out the game and see what's happening : http://gamejolt.com/games/thuglifealpha/61660
Thanks again! :)
Without seeing your code it is difficult to find exact issues. But I you should start from finding code where new objects are instantiated/destroyed. It causes GC to collect unused objects and allocate new memory. And soon your free memory becomes so fragmented that there is no suitable memory area to allocate new object.
I strongly recommend to read articles about optimization for Unity
I am using GCD to get memory pressure notifications.
GCD documentation describes some constants like so:
DISPATCH_MEMORYPRESSURE_WARN
The system memory pressure condition is at the warning stage. Apps
should release memory that they do not need right now.
DISPATCH_MEMORYPRESSURE_CRITICAL
The system memory pressure condition is at the critical stage. Apps
should release as much memory as possible.
Seems logical that I should free unused memory. However, in other places (man pages and source code) I find this note related to these constants:
Elevated memory pressure is a system-wide condition that applications
registered for this source should react to by changing their future
memory use behavior, e.g. by reducing cache sizes of newly initiated
operations until memory pressure returns back to normal.
However, applications should NOT traverse and discard existing caches
for past operations when the system system tem memory pressure enters
an elevated state, as that is likely to trigger VM operations that
will further further ther aggravate system memory pressure.
This confuses me. So should I free memory, or should I just stop allocating new memory?
MacOS has a virtual memory (VM) system that uses a backing store: the file system. The file system is used to hold memory that is not currently in use. When the system is running low on real memory (RAM), things in memory that are not actively being used can be written to disk and loaded back into RAM later.
iOS has a virtual memory system but not a backing store. When memory runs low the system asks apps to lower their memory footprint. If that does not free up enough memory the system will start killing apps.
The guidance you are quoting from the libdispatch headers is referring to the MacOS virtual memory system, not iOS.
On iOS an application should discard objects and reduce cache sizes when handling a memory warning. Particular attention should be paid to objects that are using dirty (non-purgeable) memory. This is memory the system can not automatically reuse on its own - it must be discarded by the application first. In a typical iOS application images (pictures) use the most dirty memory.
We have a multi-threaded client - server project, we recently upgraded the server side applications on 64 - bit architecture. Solved many problems, our application now works steadily week under a heavy load. But after this period, the application on the server crashes with "Out of memory" error. At this time, free memory is available in large quantities, it seems that the problem of memory fragmentation. Is there any possibility to defragment memory, some tools? Or may be some other reasons "Out of memory" in a similar situation?
Memory allocation:
Total amount of memory : 96Gb
Physical : 48Gb
Virtual : 48Gb
The amount of free physical memory at the time of the collapse : 3GB
The amount of free virtual memory at the time of collapse : 45Gb
Maximum size of memory allocated per thread : 1GB
As you have surmised, your problem is fragmentation. There's nothing you can do to defragment memory--any tool that would attempt to do so would have to have a complete map of every pointer in your program. Note that even .NET's garbage collector can't accomplish this with the large object heap, I have crashed a 32-bit net application with only 100mb actually used.
Instead, what you need to do is avoid the fragmentation in the first place. Generally that means object pools, saving old objects for reuse rather than freeing them and later reallocating them.
Another option (if the service isn't time critical and needs to be online 100% of every second) is to restart your service every 24 hours or so (either via the task scheduler or from within your own program).
If from within your own program, you can do it in one of two ways, depending on what type of service you have (if there can exist two instances of your service at the very same - brief - time):
1) Execute a second instance of your service from within your currently running service and then terminate
2) Execute a tiny helper program that waits f.ex. 5 seconds and then (re)starts your service, then terminate your currently running service
But the best way would be to avoid the fragmentation in the first place, as Loren Pechtel writes.
I have an application that loads 170 files (let’s say they are text files) from disk in individual objects and kept in memory all the time. The memory is allocated once when I load those files from disk. So, there is no memory fragmentation involved. I also use FastMM to make sure my applications never leaks memory.
The application compares all these files with each other to find similarities. Over-simplified we can say that we compare text strings but the algorithm is way more complex as I have to allow some differences between strings. Each file is about 300KB. Loaded in memory (the object that holds it) it takes about 0.4MB of RAM. So, the running app takes about 60MB or RAM (working set). It processes the data for about 15 minutes. The thing is that it generates over 40 million page faults.
Why? I have about 2GB of free RAM. From what I know Page Faults are slow. How much they are slowing down my program?
How can I optimize the program to reduce these page faults? I guess it has something to do with data locality. Does anybody know some example algorithms for this (Delphi)?
Update:
But looking at the number of page faults (no other application in Task Manager comes close to mine, not even by far) I guess that I could increase the speed of my application IF I manage to optimize memory layout (reduce the page faults).
Delphi 7, Win 7 32 bit, RAM 4GB (3GB visible, 2GB free).
Caveat - I'm only addressing the page faulting issue.
I cannot be sure but have you considered using Memory Mapped files? In this way windows will use the files themselves as the paging file (rather than the main paging file pagrefile.sys). If the files are read only then the number of page faults should theoretically decrease as the pages won't need to written out to disk via the paging file as windows will just load the data from the file itself as needed.
Now to reduce files from paging in and out you need to try and go through the data in one direction so that as new data is read, older pages can be discarded for ever. Here is where you trade off going over the files again and caching data - the cache has to be stored somewhere.
Note that Memory Mapped files is how windows loads .dlls and .exes amongst other things. I've used them to scan though gigabyte files without hitting memory limits (we had MBs in those days and not GBs of ram).
However from the data you describe I'd suggest the ability to not go back ovver files will reduce the amount of repaging going on.
On my machine most pagefaults are reported for developer studio which is reported to have 4M page faults after 30+ minutes total CPU time. You get 10 times more, in half the time. And memory is scarce on my system. So 40M faults seems like a lot.
It could just maybe be you have a memory leak.
the working set is only the physical memory in use for your application. If you leak memory, and don't touch it, it will get paged out. You will see the virtual memory useage (or page file use) increase. These pages might be swapped back in when the heap memory walks the heap, to get swapped out again by windows.
Because you have a lot of RAM, the swapped out pages will stay in physical memory, as nobody else needs them. (a page recovered from RAM counts as a soft fault, from disk as a hard one)
Do you use an exponential resize system ?
If you grow the block of memory in too small increments while loading, it might constantly request large blocks from the system, copy the data over, and then release the old block (assuming that fastmm (de)allocates very large blocks directly from the OS).
Maybe somehow this causes a loop where the OS releases memory from your app's process, and then adds it again, causing page faults on first write.
Also avoid Tstringlist.load* methods for very large files, IIRC these consume twice the space needed.
In my Windows XP Task Manager, some processes display a higher value in the Mem Usage column than the VMSize. My Firefox instance, for example shows 111544 K as mem usage and 100576 K as VMSize.
According to the help file of Task Manager Mem Usage is the working set of the process and VMSize is the committed memory in the Virtual address space.
My question is, if the number of committed pages for a process is A and the number of pages in physical memory for the same process is B, shouldn't it always be B ≤ A? Isn't the number of pages in physical memory per process a subset of the committed pages?
Or is this something to do with sharing of memory among processes? Please explain. (Perhaps my definition of 'Working Set' is off the mark).
Thanks.
Virtual Memory
Assume that your program (eg Oracle) allocated 100 MB of memory upon startup - your VM size goes up by 100 MB though no additional physical / disk pages are touched. ie VM is nothing but memory book keeping.
The total available physical memory + paging file memory is the maximum memory that ALL the processes in the system can allocate. The system does this so that it can ensure that at any point time if the processes actually start consuming all that memory it allocated the OS can supply the actual physical pages required.
Private Memory
If the program copies 10 MB of data into that 100 MB, OS senses that no pages have been allocated to the process corresponding to those addresses and assigns 10 MB worth of physical pages into your process's private memory. (This process is called page fault)
Working Set
Definition : Working set is the set of memory pages that have been recently touched by a program.
At this point these 10 pages are added to the working set of the process. If the process then goes and copies this data into another 10 MB cache previously allocated, everything else remains the same but the Working Set goes up again by 10 Mb if those old pages where not in the working set. But if those pages where already in the working set, then everything is good and the programs working set remains the same.
Working Set behaviour
Imagine your process never touches the first 10 pages ever again, in which case these pages are trimmed off from your process's working set and possibly sent to the page file so that the OS can bring in other pages that are more frequently used. However if there are no urgent low memory requirements, then this act of paging need not be done and OS can act as if its rich in memory. In this case the working set simply lets these pages remain.
When is Working Set > Virtual Memory
Now imagine the same program de-allocates all the 100 Mb of memory. The programs VM size is immediately reduced by 100 MB (remember VM = book keeping of all memory allocation requests)
The working set need not be affected by this, since that doesn't change the fact that those 10 Mb worth of pages where recently touched. Therefore those pages still remain in the working set of the process though the OS can reclaim them whenever it requires.
This would effectively make the VM < working set. However this will rectify if you start another process that consumes more memory and the working set pages are reclaimed by the OS.
XP's Task Manager is simply wrong. EDIT: If you don't believe me (and someone doesn't, because they voted this down), read Firefox 3 Memory Usage. I quote:
If you’re looking at Memory Usage
under Windows XP, your numbers aren’t
going to be so great. The reason:
Microsoft changed the meaning of
“private bytes” between XP and Vista
(for the better).
Sounds like MS got confused. You only change something like that if it's broken.
Try Process Explorer instead. What Task Manager labels "VM Size", Process Explorer (more correctly) labels "Private Bytes". And in Process Explorer, Working Set (and Private Bytes) are always less than or equal to Virtual Size, as you would expect.
File mapping
Very common way how Mem Usage can be higher than VM Size is by using file mapping objects (hence it can be related to shared memory, as file mapping is used to share memory). With file mapping you can have a memory which is committed (either in page file or in physical memory, you do not know), but has no virtual address assigned to it. The committed memory appears in Mem Usage, while used virtual addresses usage is tracked by VM Size.
See also:
What does “VM Size” mean in the Windows Task Manager? on Stackoverflow
Breaking the 32 bit Barrier in my developer blog
Usenet discussion Still confused why working set larger than virtual memory
Memory usage is the amount of electronic memory currently allocated to the process.
VM Size is the amount of virtual memory currently allocated to the process.
so ...
A page that exists only electronically will increase only Memory Usage.
A page that exists only on disk will increase only VM Size.
A page that exists both in memory and on disk will increase both.
Some examples to illustrate:
Currently on my machine, iexplore has 16,000K Memory Usage and 194,916 VM Size. This means that most of the memory used by Internet Explorer is idle and has been swapped out to disk, and only a fraction is being kept in main memory.
Contrast with mcshield.exe with has 98,984K memory usage and 98,168K VM Size. My conclusion here is that McAfee AntiVirus is active, with at lot of memory in use. Since it's been running for quite some time (all day, since booting), I expect that most of the 98,168K VM Size is copies of the electronic memory - though there's nothing in Task Manager to confirm this.
You might find some explaination in The Memory Shell Game
Working Set (A) – This is a set of virtual memory pages (that are committed) for a process and are located in physical RAM. These pages fully belong to the process. A working set is like a "currently/recently working on these pages" list.
Virtual Memory – This is a memory that an operating system can address. Regardless of the amount of physical RAM or hard drive space, this number is limited by your processor architecture.
Committed Memory – When an application touches a virtual memory page (reads/write/programmatically commits) the page becomes a committed page. It is now backed by a physical memory page. This will usually be a physical RAM page, but could eventually be a page in the page file on the hard disk, or it could be a page in a memory mapped file on the hard disk. The memory manager handles the translations from the virtual memory page to the physical page. A virtual page could be in located in physical RAM, while the page next to it could be on the hard drive in the page file.
BUT: PF (Page File) Usage - This is the total number of committed pages on the system. It does not tell you how many are actually written to the page file. It only tells you how much of the page file would be used if all committed pages had to be written out to the page file at the same time.
Hence B > A...
If we agree that B represents "mem usage" or also PF usage, the problem comes from the fact it actually represents potential page usages: in Xp, this potential file space can be used as a place to assign those virtual memory pages that programs have asked for, but never brought into use...
Memory fragmentation is probably the reason:
If the process allocates 1 octet, it counts for 1 octet in the VMSize, but this 1 octet requires a physical page (4K on windows operating system).
If after allocating/freeing memory, the process has a second octet that is separated by more than 4K from the first one, this second octet will always be stored on a separate physical page than the 1 one.
So the VM Size count is 2 octets but the Memory Usage is 2 pages== 8K
So the fact that MemUsage is greater than VMSize shows that process does a lot of allocation and deallocation and fragments the memory.
This could be because the process is started a long time ago.
Or else there is place for optimization ;-)