Announcement

Collapse
No announcement yet.

Go 1.8 Baking Garbage Collector Improvements, Lower Cgo Overhead

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Go 1.8 Baking Garbage Collector Improvements, Lower Cgo Overhead

    Phoronix: Go 1.8 Baking Garbage Collector Improvements, Lower Cgo Overhead

    The first release candidate of Google's Go 1.8 programming language is now available ahead of the official launch expected next month...

    http://www.phoronix.com/scan.php?pag...&px=Go-1.8-RC1

  • #2
    The GC situation is a bit nuanced than that, see the following link for a review of what's what:

    https://blog.plan99.net/modern-garba...n-911ef4f8bd8e

    > I have no doubt that many Go users are very happy with the new runtime. But I have a bone to pick with these claims — to me it comes across like a misleading piece of marketing. As these claims are getting repeated across the blogosphere, it’s time to take a deeper look at them.

    Comment


    • #3
      Originally posted by dsvensson View Post
      The GC situation is a bit nuanced than that, see the following link for a review of what's what:

      https://blog.plan99.net/modern-garba...n-911ef4f8bd8e

      > I have no doubt that many Go users are very happy with the new runtime. But I have a bone to pick with these claims — to me it comes across like a misleading piece of marketing. As these claims are getting repeated across the blogosphere, it’s time to take a deeper look at them.
      Well, that is one way to look at it. Bu the bigger picture is a lot of what Go does flies in the face of decades of making languages more complicated (e.g. it doesn't even have inheritance). But sometimes (often) simpler is better.
      I'm not familiar with Go's GC so I'm not even sure its performance is a sore point.

      Comment


      • #4
        If I remember correctly. the other thing that the Go GC does which is useful is that when it needs extra time for GC it takes it from the threads that are doing allocation. This works out great because those are the same threads creating more garbage to collect later. so it is assigning the cost to the right place.

        Like every GC language, the ultimate way to speed up the program is to not create any garbage memory. Use large byte buffers and slices of those buffers instead of copies. Recycle instead of releasing them. That technique alone can increase program speed dramatically and it is a lot easier to do in Go than it is in Java.

        Comment


        • #5
          Originally posted by dsvensson View Post
          The GC situation is a bit nuanced than that, see the following link for a review of what's what:

          https://blog.plan99.net/modern-garba...n-911ef4f8bd8e

          > I have no doubt that many Go users are very happy with the new runtime. But I have a bone to pick with these claims — to me it comes across like a misleading piece of marketing. As these claims are getting repeated across the blogosphere, it’s time to take a deeper look at them.
          I read that article a couple weeks ago and found it to be pretty sloppy. Overall it's obviously written by someone with a lot of experience, but it focuses in the initial release of the Go GC when there have been major updates in the year and a half since. Why didn't it talk about Go's current GC instead? Another thing it was weird about was saying that Java has a GC with similar latency, and then it mentions the latency of this Java GC low latency option, which is an order of magnitude slower than Go's. It also doesn't discuss that Go has better escape analysis, making the GC not needed much of the time where it would be in Java. Overall, the author seemed very smart, but I couldn't help but wonder if someone with so much experience and such huge errors in their writing was blinded by an affection for Java and picked facts in a way that could be misleading.

          Comment


          • #6
            Originally posted by Zan Lynx View Post
            If I remember correctly. the other thing that the Go GC does which is useful is that when it needs extra time for GC it takes it from the threads that are doing allocation. This works out great because those are the same threads creating more garbage to collect later. so it is assigning the cost to the right place.
            In my opinion, it is (just) a heuristic. Without detailed examination of code and data it is impossible to tell whether giving more or less CPU time to a particular set of threads/goroutines will benefit memory consumption and garbage collection.

            Comment


            • #7
              Originally posted by bug77 View Post

              Well, that is one way to look at it. Bu the bigger picture is a lot of what Go does flies in the face of decades of making languages more complicated (e.g. it doesn't even have inheritance). But sometimes (often) simpler is better.
              I'm not familiar with Go's GC so I'm not even sure its performance is a sore point.
              The simplicity of Go creates some other mismatches in the comparison to Java. Java makes no guarantees about layout of memory when you define a class and instantiate it, there is inherent overhead to instantiating objects (I want to say this is like 128bit at the low end, possibly more) and then no promises about where the data owned by an object actually resides in memory, that data is often instances of objects itself which have that "object overhead" of their own. Java strings, as an example, are interned and live nowhere near the actual object that references them in many cases. Go's model is much lower level, a struct pretty much defines memory usage as it would in C. Go effectively has bytes, integers of various sizes, floats, structs and then arrays of those.

              The simplicity of Go almost certainly results in entirely different types of applications being written than are in Java. I've worked on Java apps running on application servers that had 64GB sized heaps, doing a full GC (across the entire app server) on that is just a different sort of thing than something a magnitude smaller. I've not heard any loud rumblings about Go's GC latency, just sort of the normal noise from anti-GC folks. It's there though, occasionally some aspect of your application may stall briefly while it's GCing, if you're testing things and looking for consistency then there maybe that an inconsistency just due to the nature of it all with no explanation you can provide with your code. Eric Raymond is writing an NTP server and is pondering replacing C with Go or Rust, locking out GC during some critical sections in that type of application is the biggest potential problem I've heard about. A lot of this is the Go community staying on top of the issue before it's a real headache though.

              Comment


              • #8
                Originally posted by Nelson View Post
                The simplicity of Go creates some other mismatches in the comparison to Java. Java makes no guarantees about layout of memory when you define a class and instantiate it, there is inherent overhead to instantiating objects (I want to say this is like 128bit at the low end, possibly more) and then no promises about where the data owned by an object actually resides in memory, that data is often instances of objects itself which have that "object overhead" of their own. Java strings, as an example, are interned and live nowhere near the actual object that references them in many cases. Go's model is much lower level, a struct pretty much defines memory usage as it would in C. Go effectively has bytes, integers of various sizes, floats, structs and then arrays of those.

                The simplicity of Go almost certainly results in entirely different types of applications being written than are in Java. I've worked on Java apps running on application servers that had 64GB sized heaps, doing a full GC (across the entire app server) on that is just a different sort of thing than something a magnitude smaller. I've not heard any loud rumblings about Go's GC latency, just sort of the normal noise from anti-GC folks. It's there though, occasionally some aspect of your application may stall briefly while it's GCing, if you're testing things and looking for consistency then there maybe that an inconsistency just due to the nature of it all with no explanation you can provide with your code. Eric Raymond is writing an NTP server and is pondering replacing C with Go or Rust, locking out GC during some critical sections in that type of application is the biggest potential problem I've heard about. A lot of this is the Go community staying on top of the issue before it's a real headache though.
                In the distant future, it might be possible to optimize the memory layout of Go variables which aren't escaping to the C world and to the OS (operating system) world. For example, if the Go compiler knows the concrete type of an interface value it may decide to replace the interface type of a particular variable or field with the concrete type. However, in golang such optimizations aren't as necessary as in Java because of Java's relatively inefficient generic/default/unoptimized memory layout of objects.

                Go is more amenable to memory layout optimizations than C because there is a smaller number of ways in which type information about Go variables can be destroyed by a Go source code.

                The capacity of memory modules isn't going to stop growing in the near future. In consequence there is very little pressure on compilers and runtimes to optimize for memory consumption.

                Comment


                • #9
                  Originally posted by atomsymbol View Post
                  The capacity of memory modules isn't going to stop growing in the near future. In consequence there is very little pressure on compilers and runtimes to optimize for memory consumption.
                  You might think so, but I find there's quite a lot of pressure to control memory usage.

                  It makes all the difference in how many containers can be run on each host. Using Kubernetes, I can define memory limits. Say that a micro-service is known to stay under 64 MB. I can set its memory limit to 64 MB and now I can run hundreds of copies on one node. Or I can build it differently and make a single gigantic THING that tries to serve hundreds of clients per second using 2 GB and 200 threads. The second choice is a lot more fragile though, and harder to scale across a bunch of cheap, temporary EC2 nodes.

                  Comment


                  • #10
                    Originally posted by Palu Macil View Post
                    Another thing it was weird about was saying that Java has a GC with similar latency, and then it mentions the latency of this Java GC low latency option, which is an order of magnitude slower than Go's.
                    But he's talking about the trade-offs, right? He said that for the Java low latency option most of the pauses are less than 1ms, and then every once in a while a 50-100 ms pause has to occur. So most of the time it's as quick as Go for latency, with occasional hiccups but average latency is the same. If the total throughput is better, then for some applications it's sufficient. If the total throughput is worse, then maybe Go is a better option.


                    Comment

                    Working...
                    X