19.0.0 released Nov 08, 2023
Memory handling

Managed and unmanaged
Memory allocated by Vely statements (and internally by Vely) can be managed or unmanaged. By default it's managed and it might be the only kind you use.  

Managed memory used by Vely statements is tracked and always fully freed at the end of a request, even if you don't do it. In fact that is preferrable in most cases (more on this below). This is the default behavior. In this case, your program is in "managed memory mode".

Note that memory used for some constructs (see for instance "process-scope" clause in new-tree or new-hash) can stay allocated for the life of the process. Such memory is not released at the end of request, but rather it stays for all requests served by the process, unless it's manually deleted. These cases are clearly documented and serve a specific purpose.

Unmanaged memory is rarely used; more on it further down.
Allocated memory
Some Vely statements allocate memory for their results. Each statement's documentation specifies the clause(s) that allocate memory. Those that have not been so specified do not allocate memory. If memory cannot be allocated, your request will error out (see error-handling); this does not affect other requests.
Managed memory
All managed memory is automatically freed at the end of each request, so in general you may not need to free memory at all. If needed, you can free memory with delete-mem or reallocate with resize-mem, or use statements that explicitly do that (such as delete-query for instance); however, unless your program uses lots of memory for longer, it may make sense to not do that and let Vely release it at the end of the request. The reasons for this are:
In the end, it is up to you whether to release memory explicitly, let Vely do it, or a bit of both.

Managed memory is freed even if it is no longer accessible to the program, thus preventing memory leaks; this is important for stability of long-running processes.

Note that managed memory is not the same as "garbage collector", which can consume considerable resources. Vely's managed memory is very light because it only tracks memory used by Vely statements and such memory is simply released at the end of a request; there is nothing more to it - no scanning of the heap, tracking of objects, counting references, compacting memory etc. Hence "managed memory" is managed so lightly to have virtually no impact on performance. This is in part made possible by the fact that Vely does not use multithreaded computing; rather parallelism is achieved by using resident stay-in-memory processes which are single-threaded.
Internal process memory
Memory needed for cross-request purposes, such as prepared database statements or process configuration data, is kept for the life of the process. This memory is used and managed internally by Vely.
Memory reuse
Any of the Vely statement-APIs that return allocated memory will always create it new. In other words, the previously allocated memory will not be reused by default.

This is so that common and hard-to-track bugs relating to memory reuse, proper sizing and re-allocation can be avoided, such as passing non-Vely allocated pointers, bad pointers or memory of insufficient allocation. In addition, this approach may increase performance because allocating memory is generally faster than reallocating; given requests are short and frequent by nature, it means increased productivity and performance.

Either way, you can always explicitly reuse memory during request processing by freeing previously allocated memory of any statement that does so, see delete-mem or any other specialized statement (such as delete-query or delete-json for example).
Open file descriptors
Any files opened by open-file statement are automatically closed by Vely at the end of the request. This enhances stability of long-running server processes because Linux system by default offers only about 1000 open files to a process. A bug can quickly exhaust this pool and cause a malfunction or a crash - Vely prevents this by closing any such open files when the request ends. Note that this is true whether your program is currently in managed or unmanaged memory mode.
Unmanaged memory
Unmanaged memory is not tracked and you have to manually free it. It uses the same allocation as standard C's malloc() memory. Memory allocated is unmanaged when "off" clause is used in manage-memory - this is "unmanaged memory mode". Unmanaged memory is used only in special circumstances and in general should not be used without a good reason. See global-process-data.

Memory allocated in managed mode can only be freed or reallocated while in managed mode. And conversely, memory allocated in unmanaged mode can only be freed or reallocated while in unmanaged mode. Attempting otherwise will cause your program to error out.

By default, memory usage is managed. Use manage-memory with "off" clause to enter unmanaged mode, and "on" clause to revert to managed mode. Here is an example of unmanaged memory mode:
// Enter unmanaged mode
manage-memory off
new-mem var size 1024
// Exit managed mode
manage-memory on

If you are using unmanaged memory, then you must explicitly manage it by using delete-mem or resize-mem, or use statements that explicitly do that (such as delete-query for instance) - these operations must be performed in unmanaged memory mode as well.
See also
See all

You are free to copy, redistribute and adapt this web page (even commercially), as long as you give credit and provide a dofollow link back to this page - see full license at CC-BY-4.0. Copyright (c) 2019-2023 Dasoftver LLC. Vely and elephant logo are trademarks of Dasoftver LLC. The software and information on this web site are provided "AS IS" and without any warranties or guarantees of any kind. Icons from table-icons.io copyright PaweĊ‚ Kuna, licensed under MIT license.