Giter Site home page Giter Site logo

Comments (10)

sakno avatar sakno commented on June 2, 2024 1

How then does it InlineArray(x) is it not the same stack space

Do you mean this feature? If yes, it's just a macro for JIT/AOT compiler. It follows the same rules as regular struct with copy semantics:

[System.Runtime.CompilerServices.InlineArray(3)]
public struct Buffer
{
    private int _element0;
}

// it's the same as
[StructLayout(LayoutKind.Sequential)]
public struct Buffer
{
    private int _element0, element1, element2;
}

When you trying to return Buffer or store it in a field, the compiler produces copy-by-value of the entire value type. No magic here.

Unmanaged rather to just renting from the pool?

Depends on the use case. Memory pooling can be a source of frequent full GC. For instance, you trying to decode binary data to base64, but don't know the size of that binary data (even approximately). In this case, unmanaged memory is better because you don't need to wait for full GC to release the memory back to the heap, and the memory block is less likely to be reused. If you know the size of the binary data approximately (or const which is ideal case), then use memory pooling. Once again,

stackalloc[32]; // 32 is const, this is a good use case for stackalloc
stackalloc[variable]; // still fine, if you known the upper bound of 'variable' and it's checked somewhere above explicitly
stackalloc[a * b]; // bad if 'a * b' never checked for its bounds. In this case, replace stackalloc with the memory allocated in the heap

This is why the following pattern exists:

const int stackallocThreshold = 20;
var memory = size <=stackallocThreshold
  ? new MemoryRental<byte>(stackalloc byte[stackallocThreshold], size)
  : new MemoryRental<byte>(size);

from dotnext.

CodingMadness avatar CodingMadness commented on June 2, 2024 1

Gotcha. Thanks.

from dotnext.

sakno avatar sakno commented on June 2, 2024

MemoryOwner<T> is not a ref struct, therefore it can't have ref fields or fields of ref struct type. This is limitation of .NET GC. GC cannot track interior pointers located in the heap. Moreover, proposed change breaks backward compatibility. Use MemoryRental<T> instead. Probably, C# compiler prevents you from storing MemoryRental<T> in a field of regular class or struct. This is fine, because it may points to stack-allocated memory and this memory doesn't exist out of stackframe.

static MemoryRental<int> M()
{
   Span<int> span = stackalloc int[10];
   return new MemoryRental<int>(span); // how this should work?
}

from dotnext.

sakno avatar sakno commented on June 2, 2024

In the same time MemoryOwner<T> is able to represent unmanaged memory allocated using NativeMemory class from .NET library. To do that, you can use UnmanagedMemoryAllocator class.

from dotnext.

sakno avatar sakno commented on June 2, 2024

Copy method allows to make a copy of memory block and represent the copy as MemoryOwner<T> using any memory allocator.

from dotnext.

CodingMadness avatar CodingMadness commented on June 2, 2024

Okay, good to know

from dotnext.

CodingMadness avatar CodingMadness commented on June 2, 2024

MemoryOwner<T> is not a ref struct, therefore it can't have ref fields or fields of ref struct type. This is limitation of .NET GC. GC cannot track interior pointers located in the heap. Moreover, proposed change breaks backward compatibility. Use MemoryRental<T> instead. Probably, C# compiler prevents you from storing MemoryRental<T> in a field of regular class or struct. This is fine, because it may points to stack-allocated memory and this memory doesn't exist out of stackframe.

static MemoryRental<int> M()
{
   Span<int> span = stackalloc int[10];
   return new MemoryRental<int>(span); // how this should work?
}

Although you could allow it by [UnscopedRef] attribute over the respective function, to avoid the compiler error and call a Property: public Span<T> Data => new Span(_ptr, _count) where _ptr is a T* inside your MemoryOwner<T> because I could then pass an X-Amount to use to allocate on stack, and internally ofc you can check if the requested Memory would overflow and then pass that to unmanaged or rent from pool. take a look:

[UnscopedRef]   //------------->important, to allow the stackalloc expression!
private MemoryOwner<byte> _pool { get; }

public MyStruct(int amount)
{
         //I think you can check internally, with "StackAllocThreshold" constant, if I can do this, if I cant then the entire `amount` will be used to rent from pool or unmamaged, however the choice, but if it does not exceed stacklimit, just use stackalloc
        _pool = new(stackalloc byte[amount]);
}


public void DoWork() =>//do smth with _pool!

from dotnext.

sakno avatar sakno commented on June 2, 2024

_pool = new(stackalloc byte[amount]);

That is completely invalid, stack memory doesn't exist out of the method. You can crash the entire program with SIGTERM in attempt to access the memory.

UnscopedRef

It is invented to instruct the compiler that the enclosing interior pointer escapes the marked method or getter. Nothing more.

from dotnext.

CodingMadness avatar CodingMadness commented on June 2, 2024

How then does it InlineArray(x) is it not the same stack space which is being allocated here with the same mechanics?

from dotnext.

CodingMadness avatar CodingMadness commented on June 2, 2024

Another related question, when would you prefer to allocate Unmanaged rather to just renting from the pool? (except the request for pooling memory is to huge)

from dotnext.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.