I think the most extreme variant of this sharing is when you build up a
"binary tree" that keeps pointing both left and right pointers to the same
underlying structure. A tree of size K is supposed to have around 2^K nodes
but in reality the memory layout is around K nodes in size. Suppose we
define (brace for some Erlang):

gather(X, 0) -> X;
gather(X, K) -> gather([X,X], K-1).

as a function and then call it with gather(<<"hello">>, 24), we obtain a
tree of size 2^24, yet it doesn't take up too much internal memory due to
sharing. To see how extreme it is, lets define

run() ->
    Parent = self(),
    spawn_link(
      fun() ->
              Res = gather(<<"hello">>, 24),
              {ok, Sock} = gen_tcp:connect({127,0,0,1}, 2000, [binary,
{packet, 4}]),
              gen_tcp:send(Sock, Res),
              gen_tcp:close(Sock),
              Parent ! {proc_info, erlang:process_info(self(), memory)},
              ok
      end),
    receive
        {proc_info, Info} ->
            Info
    after 5000 ->
            {error, timeout}
    end.

This creates a process, opens a local TCP socket on port 2000 (we'll have a
nc(1) patiently waiting in another shell piped to wc(1)), writes the tree
to the socket, and then closes it before returning. The output produced by
netcat has size around 81 Megabytes. Yet, the memory reported in the above
usage is around 5.7 Kilobytes for my installation. Sharing is caring, I
guess :)

Of course, this only works if your data is truly immutable. Mutating the
structure can yield some vastly different results and YMMV in that case.


On Thu, Apr 13, 2017 at 6:46 PM Ian Lance Taylor <i...@golang.org> wrote:

> On Thu, Apr 13, 2017 at 9:31 AM,  <sdic...@watchtower-security.com> wrote:
> > https://play.golang.org/p/swRxxCbb65
> >
> > Surely s1 uses more than 8 bytes.
>
> Unfortunately, your question is not well defined.  s1 itself is 8
> bytes.  If you write `s3 := s1` and ask for the size of s3, it too
> will be 8 bytes.  There is also string data in memory, and both s1 and
> s3 will share that string data.  There isn't a clear answer to "how
> much space is taken by this value and everything to which it points."
>
> Ian
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to