I have a simple question about memory management in Julia code. Coming from a C++ background with all that rvalue reference madness and move semantics stuff, I got my brain damaged, and I am having a hard time trying to reason about memory management again in other languages.
Consider the following cases:
Case 1
I have an immutable struct that requires a decent amount of memory (e.g. mesh with vertices, edges, triangles). By using composition, I define other concepts (e.g. path):
abstract type AbstractMesh end
struct Mesh <: AbstractMesh
vertices::Vector{...}
edges::Vector{...}
triangles::Vector{...}
end
struct Path{M<:AbstractMesh}
m::M
other_attributes
end
# define behavior of Path using the mesh inside
coords(p::Path, location) = somefunc(p.m, location)
Questions
- Will the data stored in the Mesh object be copied to the Path object? If yes, how to avoid this?
- How the keyword
mutable
would affect the copying in this case? Consider two cases: a) adding mutable
to the Mesh
type, and b) adding mutable
to the Path
type.
Case 2
I have a big container object (e.g. Container) that I will be passing to functions:
struct Container
data::HugeDataVector
end
Questions
- When will a call
f(c)
where c
is a Container
create a copy of the object inside of the body of f
? How the mutable
keyword plays here?
- I have heard that immutable objects are always copied around, is that correct? If yes, how do you enforce “const semantics” to a type without killing performance?
1 Like
Things are never copied implicitly. The mutable
keyword has nothing to do with this, it only says whether you are allowed to modify (rebind) the fields of the struct (which might determine if it will be stored on the stack or the heap).
The semantics are that they are always copied. If the struct is big enough the compiler can just pass them by reference. Since they are immutable, you will never know the difference.
2 Likes
Thank you @kristoffer.carlsson, so objects are never copied in the examples above? Maybe if you could address the questions I raised, it would be even clearer…
When you say that immutable types have copy semantics, you mean that when we try to modify the object, we will get a copy, but not otherwise? That sounds like an awesome feature.
The semantics are that no objects, immutable or mutable, are ever copied.
Immutables can be copied if necessary.
2 Likes
No.
No, you can’t modify an immutable (see the correction to my statement above though).
1 Like
All values in julia has the same semantics as pointers or lvalue reference in C, with the additional semantics that you are not allowed to mutate some of the references. (similar to a strict version of const)
Undefined and you are not able to notice the difference.
mutable makes it invalid to copy in general (the compiler can still copy if it proved that the object doesn’t escape and doing that increases performance).
Semantically, never. When the compiler thinks it’s valid and beneficial to do so in reality. mutable makes it harder to proof the validity in general, but a mutable
on the Container
type has no effect at all.
No.
Report a performance bug if the compiler heuristic is sub-optimal.
Also, do note that copy
here corresponds to copy of POD in C++. The compiler never, ever, call copy
.
2 Likes
Thank you all, it is really to nice to see that no copies are being made at all, and that this machinery is hidden from the user to some extent. Awesome design