Memory management

V avoids doing unnecessary allocations in the first place by using value types, string buffers, promoting a simple abstraction-free code style.

Most objects (~90-100%) are freed by V’s autofree engine: the compiler inserts necessary free calls automatically during compilation. Remaining small percentage of objects is freed via reference counting.

The developer doesn’t need to change anything in their code. “It just works”, like in Python, Go, or Java, except there’s no heavy GC tracing everything or expensive RC for each object.

For developers willing to have more low level control, autofree can be disabled with -noautofree.

Note: right now autofree is hidden behind the -autofree flag. It will be enabled by default in V 0.3.

For example:

  1. import strings
  2. fn draw_text(s string, x int, y int) {
  3. // ...
  4. }
  5. fn draw_scene() {
  6. // ...
  7. name1 := 'abc'
  8. name2 := 'def ghi'
  9. draw_text('hello $name1', 10, 10)
  10. draw_text('hello $name2', 100, 10)
  11. draw_text(strings.repeat(`X`, 10000), 10, 50)
  12. // ...
  13. }

The strings don’t escape draw_text, so they are cleaned up when the function exits.

In fact, the first two calls won’t result in any allocations at all. These two strings are small, V will use a preallocated buffer for them.

  1. struct User {
  2. name string
  3. }
  4. fn test() []int {
  5. number := 7 // stack variable
  6. user := User{} // struct allocated on stack
  7. numbers := [1, 2, 3] // array allocated on heap, will be freed as the function exits
  8. println(number)
  9. println(user)
  10. println(numbers)
  11. numbers2 := [4, 5, 6] // array that's being returned, won't be freed here
  12. return numbers2
  13. }