Hi
Can anyone shed some light on the following two questions:
1) If one allocates some memory in a program with invoke GlobalAlloc,GMEM_FIXED,SomeMemory
and the program terminates (for what ever reason) without it calling invoke GlobalFree,hMem
is that block of memory unusable until the next restart/reboot or does the O.S. take care of
releasing it again and the use of invoke GlobalFree,hMem is more for good housekeeping?
2) Can one program (exe or dll) ask the O.S. for some memory, then exit without closing it but passing the
handle to another exe or dll so it can use it or is that memory blocked and useable only by the
original program that first requested it?
If the answer to question 2 turns out to be "any program can use it" then thinking of using it as a
sort of inter-app communications buffer.
Thanks in advance
Paulo.
Quote from: Paulo on August 23, 2013, 03:55:28 AM
1) If one allocates some memory ... does the O.S. take care of
releasing it again and the use of invoke GlobalFree,hMem is more for good housekeeping?
The OS frees the heap, so freeing it is good housekeeping only. It may be important to free memory, though, while the program is still running.
Quote2) Can one program (exe or dll) ... thinking of using it as a sort of inter-app communications buffer.
Well, the answer is no, but you can use a dll to do that, see attachment to this post (http://masm32.com/board/index.php?topic=94.msg22032#msg22032).
Thank you jj2007
Will work thru the code given and adapt it to my needs.
I see your code is in MasmBasic, no problem but it does bring me to ask a question.
Being in the programming game, every now and again people tend to ask me what I would recommend
for a youngster (or beginner) to get started in Windows programming.
I used to tell them VB5 or 6 but now with it's demise, I don't really have an answer for them.
ASM, C, C++,C# and so forth (pun intended) are far too complex for an absolute beginner and more often than not
simply puts them off programming for life.
Yes it can be argued that one should start with ASM or C as it forces you to learn the "nitty gritty" of programming
and set good "habits" from the start.
However I am of the opinion that the beginner should first get some experience and confidence by starting with
some thing simpler that takes care of the finer details (like registers, handles and so on).
This (eventually) brings me to my question, even though your MasmBasic is easy, it's still too "ASM-ish" for the
beginner as it requires a lot of register use.
Have you considered making a simpler, cut down version that is more like Basic where the gory details are taken care of
in macros.
This way as the beginner gets more confidence and curiosity, will no doubt start looking at the contents of the macros
and thus progress from there?
Paulo.
I was thinking about something like this:
The main code:
include \masm32\Paulo\ASMbas\Init.inc
include \masm32\Paulo\ASMbas\Functions.inc
start:
MakeBeep 500,1000
msgbox "This is the title","and the main text"
exit
end start
Init.inc could look something like this:
.486
.model flat,stdcall
option casemap:none ; case sensitive
; ####################################################
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\comctl32.inc
include \masm32\include\winmm.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\comctl32.lib
includelib \masm32\lib\winmm.lib
includelib \masm32\lib\masm32.lib
.data
.code
and Functions.inc would contain all the macros for the "Basic" commands.
Below is a simple example showing three "Basic commands", namely MakeBeep, exit and msgbox
; =======================================
MakeBeep MACRO arg1,arg2
invoke Beep,(arg1),(arg2)
ENDM
; =======================================
exit MACRO
xor eax, eax
invoke ExitProcess,eax
ENDM
; =======================================
msgbox MACRO DisplayName,TheText:VARARG
LOCAL DisplayName
LOCAL TheText
.data
TheTitleText db DisplayName,0
TheMainText db TheText,0
.code
push MB_YESNO
push offset TheTitleText
push offset TheMainText
push 0
call MessageBox
ENDM
Obviously a lot more work is required, but you get the idea.
Paulo.
Quote from: Paulo on August 23, 2013, 05:03:15 AM
...even though your MasmBasic is easy, it's still too "ASM-ish" for the beginner as it requires a lot of register use.
Dear Paulo,
Thank you so much - you are really the first one here who complains that MB uses registers - all others complain about the opposite, i.e. that it does not even vaguely resemble assembler :biggrin:
I just uploaded my beta of an installer here (http://masm32.com/board/index.php?topic=94.msg23580#msg23580).
In case you have installed MasmBasic already, you can read a stripped version of that post with this code:
include \masm32\MasmBasic\MasmBasic.inc
Init
Inkey NoTag$(FileRead$("http://masm32.com/board/index.php?topic=94.msg23580#msg23580"))
Exit
end start ;)
Hi jj2007
The reason I mentioned the registers is that most beginners will not be too enthusiastic about them.
As an example, I have a very good friend who has been programming in VB for years and has coded some really nice stuff using it
yet if I start talking about eax, edx and so on, he looks at me as if I have just landed from the planet Zenon :biggrin:
I really like what you have done with MasmBasic and the whole idea about a Basic like language is to take away as many of the complexities
as possible and let the user concentrate on coding and learning.
Of course with this, one tends to loose some control or functionality and if that is a problem, there is always ASM. :biggrin:
Keep up the good work.
Paulo.
Hai Paulo,
Have a look at windows task manager, when the app is closed the memory is released to. Try to allocate about 4 GB on your system so you can see a significant different.
Hi Paulo,
JJ has answered your question on memory usage but its worth understanding the concept behind it as well. If a thread terminates with a BANG (page read/write fault) the OS also cleans up the mess but in terms of software design, it really is worth the effort to develop good habits. When you allocate memory, ALWAYS free it after you have finished using it because it can impact on you own running app, slow it down or make it crash if the memory leak is caught in a loop. If you have enough memory on a 32 bit OS computer you can routinely allocate up to near 2 gig in a 32 bit app and when you are using up near the limit you cannot make mistakes.
As far as you VB friend, explain it a little differently, tell him its the silicon idiot (the processor) that talks in terms of mnemonics (asm instructions) and registers and that you take that path when you are after either power or speed or both. We have a few Martians here already so coming from the planet Zenon is probably not contentious. :biggrin:
About clearing memory,it can be very important as Hutch mentioned. I once played a demo game,the graphics were very nice,and the game was kind of interesting HOWEVER,about 5 minutes into the game it started throwing out of memory errors and locked up then crashed. Now this was a game that was shareware,so the demo was get you to buy it. The memory problems I think were from NOT deallocating memory.or as Hutch said getting in a loop.
Hi all and thank you for your comments.
@Farabi
I always run with the task manager minimized and often keep an eye on running processes, although allocating 4GB to one process
might be a bit drastic. :biggrin:
@hutch
You are quite right that one should always free up any resources used up by an app when it terminates, although it's good to know
the consequences of not doing so.
As regards my earthling VB friend, he understands the concept of variables but never really bothered thinking about how those
variables are stored and how they are accessed and manipulated by the silicon idiot.
VB like most languages has strings, long,integers and so on, but being a high level language hides the user from registers
so to him it was an alien concept.
I'm slowly converting him. :biggrin:
That is the reason I'm a fan of a Basic like macro language for ASM, it eases the beginner and even those that have only
used a high level language, into ASM.
Start off using only Basic like commands and statements then slowly introduce ASM into the mix.
@anunitu
Yep, come across a few of those memory hog apps myself.
Quote from: Paulo on August 23, 2013, 03:55:28 AM
Hi
Can anyone shed some light on the following two questions:
1) If one allocates some memory in a program with invoke GlobalAlloc,GMEM_FIXED,SomeMemory
and the program terminates (for what ever reason) without it calling invoke GlobalFree,hMem
is that block of memory unusable until the next restart/reboot or does the O.S. take care of
releasing it again and the use of invoke GlobalFree,hMem is more for good housekeeping?
2) Can one program (exe or dll) ask the O.S. for some memory, then exit without closing it but passing the
handle to another exe or dll so it can use it or is that memory blocked and useable only by the
original program that first requested it?
If the answer to question 2 turns out to be "any program can use it" then thinking of using it as a
sort of inter-app communications buffer.
Thanks in advance
Paulo.
1. Memory allocated to a process is
usually cleaned up for you on exit; however, there are some circumstances where this can't be done correctly. So you should free any memory you allocated once you no longer need it - it's not like the extra function call is complicated, it's better to not be a memory hog, and it's polite :biggrin:
2. As memory is automatically cleaned up on exit, you can't rely on leaving allocated blocks 'open,' and due to the separation of process memory spaces, another process will not even be able to see your memory. What you can do, though, is create a memory-mapped file with a name - another process can then also create the same file-mapping with the same name, and they will both share access to the same memory-mapped file - which you can then use as a shared communication buffer.
Quote from: Tedd on August 28, 2013, 12:01:31 AM
1. Memory allocated to a process is usually cleaned up for you on exit; however, there are some circumstances where this can't be done correctly.
Tedd, do you have any reference for this statement? Logic says the heap gets discarded completely on ExitProcess, but I have indeed, on rare occasions, seen my PC act in slow motion after a memory-hungry program exited. I'd really be curious to get an explanation for this behaviour. Google was no help so far..
Quote2. As memory is automatically cleaned up on exit, you can't rely on leaving allocated blocks 'open,' and due to the separation of process memory spaces, another process will not even be able to see your memory.
Don't take that as an offense, please, but that phrase is really difficult to understand. Maybe you could elaborate a little bit, not only for Paulo.
JJ,
Its a characteristic of protected mode that a virtual address memory space allocated in one process is not visible to any other process. It is because real memory linear address space is only accessed by the OS in ring0. Applications running in ring3 get a virtual memory address from the OS when they allocate memory which is protected in both read and write from any other process and that is even if another process could locate the real linear address of the memory.
What you have said about laggy performance after exiting a process is due to the OS doing what is basically lazy cleanup. It will clean up the mess but it does not necessarily do it immediately. For Paolo a memory mapped file is the smart way to share memory as long as the fixed memory size is understood once allocated. With a bit of trickery a set of applications can co-operate together to all de-allocate a memory mapped file then re-allocate a bigger one but it is a lot of messing around.
Quote from: hutch-- on August 28, 2013, 10:52:40 AM
Its a characteristic of protected mode that a virtual address memory space allocated in one process is not visible to any other process...
Hutch,
Thanks for reminding us. Still, why should somebody
rely on leaving allocated blocks 'open', and how? And under which "circumstances .. this can't be done correctly"?
QuoteWhat you have said about laggy performance after exiting a process is due to the OS doing what is basically lazy cleanup.
Yes, that was my suspicion, and it probably has to do with writing zeroes to physical memory to make it ready for the next process. But I'd be grateful for a link where this behaviour is documented, and why it can take several minutes :(
Ifyou run on a 64bit with enough memory you can use 4gb memory in 32bit, and with a hack poser users could use 3gb
Quote from: jj2007 on August 28, 2013, 07:20:06 AM
Quote from: Tedd on August 28, 2013, 12:01:31 AM
1. Memory allocated to a process is usually cleaned up for you on exit; however, there are some circumstances where this can't be done correctly.
Tedd, do you have any reference for this statement? Logic says the heap gets discarded completely on ExitProcess, but I have indeed, on rare occasions, seen my PC act in slow motion after a memory-hungry program exited. I'd really be curious to get an explanation for this behaviour. Google was no help so far..
Nothing concrete, I'm afraid, just previous experience. I was working on one program that appeared to work perfectly fine, but after numerous runs, the system gradually became slower until it became unusable and I had to reboot. After eventually finding the leak, there were no more problems.
In general, private heap allocations can be cleaned up easily; the problems start once memory/objects are shared or passed between processes and certain DLLs. Anyway, why would you purposely NOT free memory, other than to save a few milliseconds on exit (really, is that important to you??)
Quote
Quote2. As memory is automatically cleaned up on exit, you can't rely on leaving allocated blocks 'open,' and due to the separation of process memory spaces, another process will not even be able to see your memory.
Don't take that as an offense, please, but that phrase is really difficult to understand. Maybe you could elaborate a little bit, not only for Paulo.
It was a reference to the way Paulo was thinking about what he wants to do. Leaving memory blocks 'open' (like leaving files open) after your process has exited, so that another process can retrieve the same memory blocks and use them. Of course you can't do this because abandoned memory blocks should be freed by the OS when you exit; and even if you could leave them open/alive, one process can't see into the memory space of another process, so it still wouldn't work.
Quote from: jj2007 on August 28, 2013, 04:24:12 PM
QuoteWhat you have said about laggy performance after exiting a process is due to the OS doing what is basically lazy cleanup.
Yes, that was my suspicion, and it probably has to do with writing zeroes to physical memory to make it ready for the next process. But I'd be grateful for a link where this behaviour is documented, and why it can take several minutes :(
Cleanup is probably done lazily, but don't expect it to be officially documented anywhere (inside info, trade secrets, can change between versions.)
Zeroing pages will be done with a background kernel thread so it shouldn't affect performance (unless there is suddenly a huge requirement for pages and the zeroed pool is already empty.)
Anyway, you can avoid all of these and many associated problems simply by cleaning up after yourself! 8)
Quote from: Tedd on August 29, 2013, 12:01:14 AMAnyway, why would you purposely NOT free memory, other than to save a few milliseconds on exit (really, is that important to you??)
Actually, my Exit macro (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1010) cleans up very thoroughly all arrays and strings. The situations where my system slowed down were caused by exceptions. But AFAIK the OS cleans up even after exceptions, right?
not exactly the same as memory allocation....
try not deleting GDI objects
or worse, not setting a DC back to original state before deleting it
Interesting discussion.
The reasons for my original question was to establish:
1) How good is windows at cleaning up
2) What happens to allocated memory if an app crashes before releasing that memory.
Judging by the answers, I have to assume that the cleaning up process used by the OS is not very good
and any memory not released by an app is pretty much
unusable until the next reboot.
Quote from: Paulo on August 29, 2013, 10:49:00 PM
Interesting discussion.
The reasons for my original question was to establish:
1) How good is windows at cleaning up
2) What happens to allocated memory if an app crashes before releasing that memory.
Judging by the answers, I have to assume that the cleaning up process used by the OS is not very good
and any memory not released by an app is pretty much
unusable until the next reboot.
Memory that is allocated by you and used only by you will be released correctly - whether you 'forget' or if your program crashes.
Sometimes, when memory is shared between processes (usually by/via DLLs, since they are automatically shared across processes), it's possible to create situations where windows is not sure if the memory should be released - so the memory is kept, just in case (it would be released when the DLL is freed, but when every process uses that DLL, this won't happen until system shutdown.) This was particularly noticeable in earlier versions of windows, but has improved since, so it should be more difficult to achieve.
Hi Tedd
That makes perfect sense.
Thank you.