Announcement

Collapse
No announcement yet.

Miguel de Icaza Talks Up WebAssembly Greatness

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

  • #51
    Originally posted by bug77 View Post
    Luke_Wolf I'm confused, are you saying throwing 1MB of data onto the stack uses less RAM than throwing the same amount on the heap?
    It does actually because the system must allocate an extra 16 bytes for it, 8 Bytes for the pointer that goes on the stack, 8 bytes for the pointer that goes in the Garbage Collector (Note that in real world applications this extra 16 Bytes of overhead is basically mandatory, regardless of whether you're using a GC'd language or not, because of how automatic memory management systems work) .

    However that's not the main thrust of my point. The main thrust is that memory on the stack is handled by the stack, and stack memory churns... a lot. In a GC'd language if you throw what would otherwise be stack values on the heap they tend to stick around, and you're now creating an obscene amount of garbage that is waiting to be collected. Which seems to be the origin of Java's uniquely bad memory profile. Whereas C# doesn't have this problem despite being mostly similar to Java in terms of the broad strokes, because it handles this correctly.

    Comment


    • #52
      Originally posted by Luke_Wolf View Post

      It does actually because the system must allocate an extra 16 bytes for it, 8 Bytes for the pointer that goes on the stack, 8 bytes for the pointer that goes in the Garbage Collector (Note that in real world applications this extra 16 Bytes of overhead is basically mandatory, regardless of whether you're using a GC'd language or not, because of how automatic memory management systems work) .

      However that's not the main thrust of my point. The main thrust is that memory on the stack is handled by the stack, and stack memory churns... a lot. In a GC'd language if you throw what would otherwise be stack values on the heap they tend to stick around, and you're now creating an obscene amount of garbage that is waiting to be collected. Which seems to be the origin of Java's uniquely bad memory profile. Whereas C# doesn't have this problem despite being mostly similar to Java in terms of the broad strokes, because it handles this correctly.
      To jump a bit further on this point, long-lived objects go on your heap and short-lived objects like variables inside a function that don't escape the function body (are not returned to the caller or placed in a list or something) should go on the stack. The stack 'freeing' of objects as you exit the functions is the most efficient memory management you can do, the running code is going to move the stack pointer anyway.

      Did I say all of that about right?

      The JVM is riding the cutting edge of efficient garbage collection technology. The ZGC and Shenandoah garbage collectors, for example, are an amazing piece of work. But Java has to ride that cutting edge to be performance competitive. And that's only performance (speed of execution, total throughput) competitive, Java isn't memory competitive with C#, let alone C++ or C.

      Comment


      • #53
        Originally posted by Luke_Wolf View Post

        It does actually because the system must allocate an extra 16 bytes for it, 8 Bytes for the pointer that goes on the stack, 8 bytes for the pointer that goes in the Garbage Collector (Note that in real world applications this extra 16 Bytes of overhead is basically mandatory, regardless of whether you're using a GC'd language or not, because of how automatic memory management systems work) .

        However that's not the main thrust of my point. The main thrust is that memory on the stack is handled by the stack, and stack memory churns... a lot. In a GC'd language if you throw what would otherwise be stack values on the heap they tend to stick around, and you're now creating an obscene amount of garbage that is waiting to be collected. Which seems to be the origin of Java's uniquely bad memory profile. Whereas C# doesn't have this problem despite being mostly similar to Java in terms of the broad strokes, because it handles this correctly.
        JVM designers have noticed this years ago. It's why the GC has a young and a tenured generation zone. Young generation (stuff that could go on the stack, but didn't) is collected separately then tenured (long lived objects, less likely to be collected). Is JVM's memory's the most efficient? Not really, but that was never a goal. Is the GC doing the best job it can? Probably not, out of the box; but it will if you tune it right.

        Of all the differences between .Net and Java, I confess stack vs heap allocation was never something that struck me.

        Comment


        • #54
          Originally posted by Luke_Wolf View Post
          However that's not the main thrust of my point. The main thrust is that memory on the stack is handled by the stack, and stack memory churns... a lot. In a GC'd language if you throw what would otherwise be stack values on the heap they tend to stick around, and you're now creating an obscene amount of garbage that is waiting to be collected. Which seems to be the origin of Java's uniquely bad memory profile. Whereas C# doesn't have this problem despite being mostly similar to Java in terms of the broad strokes, because it handles this correctly.
          That's not how modern GCs work. The size of the heap region for eden/young generation (short lived objects) is quite small. When it becomes full, a quick collection is done and live objects are either promoted to the next region or deallocated. You do not get "obscene amounts of garbage" waiting to be collected, not unless you are purposefully creating and holding on to object references.

          Originally posted by Michael_S View Post

          To jump a bit further on this point, long-lived objects go on your heap and short-lived objects like variables inside a function that don't escape the function body (are not returned to the caller or placed in a list or something) should go on the stack. The stack 'freeing' of objects as you exit the functions is the most efficient memory management you can do, the running code is going to move the stack pointer anyway.

          Did I say all of that about right?
          Reference types never go on the stack. They always go on the heap and are managed by the runtime. Value types are stack allocated. In Java you have actual primitives (int, float, etc), and in C# you do not. There you get structure/value types which can resemble lightweight objects (and have certain restrictions), and what happens is they are boxed/unboxed so they can be treated like objects. So if you tried to add something like the integer 5 to a list of objects, it would first be converted to an object before being added. (so if you add your value type to a collection like an ArrayList, it is getting boxed behind the scenes and using EXACTLY the same memory that a Java object would use, so it's not as clear cut a distinction as you might think)

          The tricky thing is that Java does scalar replacement, so if you have a simple object that you create and use only in your method body, it may not even be an object by the time the JVM uses it because it could be transformed into simple stack allocated primitives.

          Both Java and C# are very good about dispatching short-lived objects because they use generational GCs. Deallocation costs almost nothing. Allocation is also very cheap. So this point about Java wasting a lot of memory is total nonsense because it is very good about releasing heap allocated objects. What matters is not the total number of objects you create, it's whether you are creating lots of long-lived objects or how quickly you are creating short lived ones. The rate of allocation, if high, could put pressure on the GC and reduce performance, but there will be no "wasting memory" since they are destroyed quickly enough and replaced by new ones.

          One of the challenges for Java performance has always been the boxing of primitive types (which introduces a big penalty on math heavy operations). When value types are introduced, they will alleviate that greatly.
          Last edited by cynical; 06 March 2020, 03:29 PM.

          Comment


          • #55
            Originally posted by Luke_Wolf View Post
            Real world C# programs are vastly more memory efficient than Java programs, they are within the same order as similar C++ programs. Toy C++ programs that don't require automatic memory management schemes like parent child hierarchies can still be more efficient but that's the difference we're talking about here. I made a post about this years ago where I compared the memory usage of comparable real world C++ and C# programs, and some Java programs thrown in for comparison if you want to look back through my history. If you want a simple comparison check out the memory usage of Monodevelop vs KDevelop or QtCreator vs your Java based IDE of choice with a decent sized project loaded.
            Based on what? Value types are nice but concluding that C# is "vastly more memory efficient" based on that alone is ridiculous. Do you realize that if you add your value type to an ArrayList, it is now an object? Do you realize that stack allocation is not guaranteed in the first place? Comparing two IDEs and trying to conclude something about the languages based on that is completely ridiculous. If C# was as efficient as C++, you wouldn't have so many posts on the internet complaining about its memory usage.

            You have a bias towards C#, which is fine if you like that language, but there have to be significant differences between the way Java and C# handle memory for there to be significant differences in memory usage, and that simply isn't the case. They both have fairly large runtimes and rely heavily on reference types.

            Comment


            • #56
              Originally posted by Zan Lynx View Post

              It has been a long time since you could read the Javascript code and have it make any sense. First it's compile to JS from Typescript, then it is compressed and obfuscated so every function is called "f" or "g". CSS is often done in a similar way with all of the classes and object IDs named junk like "c1" and done half in CSS text and half in Javascript.

              WASM is no worse. It can be decompiled and read about the same as obfuscated Javascript. At least it can't do x86 assembly tricks like computing a jump into unaligned code at a +1 byte offset or using Windows SEH to execute the real code during division by zero.
              Maybe yes with the user friendly names, but still you can see the function that are trying to be used like navigator.geolocation.getCurrentPosition(showPosition);
              I don't really thing that you can obfuscate everything in Javascript.
              But anyway, I will see what the future brings, if there are more advantages or disadvantages.

              Comment

              Working...
              X