标签: stack-memory

创建堆栈大小为默认值50倍的线程有什么危险?

我目前正在开发一个性能非常关键的程序,我决定探索的一条路径可能有助于减少资源消耗,增加了我的工作线程的堆栈大小,因此我可以移动float[]我将要访问的大部分数据堆栈(使用stackalloc).

我已经读过一个线程的默认堆栈大小是1 MB,所以为了移动我所有的float[]s,我必须将堆栈扩展大约50倍(到50 MB~).

我知道这通常被认为是"不安全的"并且不推荐,但在对我的当前代码进行基准测试后,我发现处理速度提高了530%!因此,我不能简单地通过这个选项而不进一步调查,这导致我的问题; 将堆叠增加到如此大的尺寸(可能出现什么问题)有什么危险,我应该采取什么预防措施来减少这种危险?

我的测试代码,

public static unsafe void TestMethod1()
{
    float* samples = stackalloc float[12500000];

    for (var ii = 0; ii < 12500000; ii++)
    {
        samples[ii] = 32768;
    }
}

public static void TestMethod2()
{
    var samples = new float[12500000];

    for (var i = 0; i < 12500000; i++)
    {
        samples[i] = 32768;
    }
}
Run Code Online (Sandbox Code Playgroud)

.net c# memory stack-memory

228
推荐指数
7
解决办法
5286
查看次数

多维数组如何在内存中格式化?

在C中,我知道我可以使用以下代码在堆上动态分配二维数组:

int** someNumbers = malloc(arrayRows*sizeof(int*));

for (i = 0; i < arrayRows; i++) {
    someNumbers[i] = malloc(arrayColumns*sizeof(int));
}
Run Code Online (Sandbox Code Playgroud)

显然,这实际上会创建一个指向一堆独立的一维整数数组的指针的一维数组,而"系统"可以在我要求时找出我的意思:

someNumbers[4][2];
Run Code Online (Sandbox Code Playgroud)

但是,当我静态声明一个2D数组时,如下一行...:

int someNumbers[ARRAY_ROWS][ARRAY_COLUMNS];
Run Code Online (Sandbox Code Playgroud)

...是否在堆栈上创建了类似的结构,还是完全是另一种形式?(即它是指针的一维数组吗?如果没有,它是什么,以及如何计算它的引用?)

另外,当我说"系统"时,究竟是什么负责解决这个问题呢?内核?或者C编译器在编译时对其进行排序?

c memory arrays stack-memory data-structures

165
推荐指数
4
解决办法
7万
查看次数

Go中结构的堆栈与堆分配,以及它们与垃圾收集的关系

我是Go的新手,我在C风格的基于堆栈的编程之间经历了一些不协调的错误,其中自动变量存在于堆栈上,并且在堆上分配了内存,以及基于Python的基于堆栈的编程,其中只有堆栈上的东西才是堆上对象的引用/指针.

据我所知,以下两个函数提供相同的输出:

func myFunction() (*MyStructType, error) {
    var chunk *MyStructType = new(HeaderChunk)

    ...

    return chunk, nil
}


func myFunction() (*MyStructType, error) {
    var chunk MyStructType

    ...

    return &chunk, nil
}
Run Code Online (Sandbox Code Playgroud)

即分配一个新结构并返回它.

如果我在C中编写它,第一个将把一个对象放在堆上,第二个将它放在堆栈上.第一个将返回一个指向堆的指针,第二个将返回一个指向堆栈的指针,该指针在函数返回时会蒸发,这将是一件坏事.

如果我用Python(或除C#之外的许多其他现代语言)编写它,那么示例2是不可能的.

我得到Go垃圾收集两个值,所以上述两种形式都没问题.

报价:

请注意,与C不同,返回局部变量的地址是完全可以的.与函数关联的存储在函数返回后仍然存在.实际上,获取复合文字的地址在每次评估时都会分配一个新实例,因此我们可以将这两行结合起来.

http://golang.org/doc/effective_go.html#functions

但它提出了几个问题.

1 - 在示例1中,结构在堆上声明.例2怎么样?在堆栈中声明的方式与在C中的方式相同,还是在堆上也是如此?

2 - 如果在堆栈上声明了示例2,那么在函数返回后它是如何保持可用的?

3 - 如果实际上在堆上声明了示例2,那么结构是如何通过值而不是通过引用传递的?在这种情况下,指针有什么意义?

heap-memory go stack-memory

146
推荐指数
4
解决办法
3万
查看次数

如何在C中的堆栈上创建结构?

我理解如何struct在堆上创建使用malloc.正在寻找struct关于在堆栈上创建一个C而不是所有文档的一些文档.似乎只谈论堆上的结构创建.

c heap-memory stack-memory

50
推荐指数
3
解决办法
3万
查看次数

堆栈和堆中的内存分配

这似乎是一个非常基本的问题,但它一直在我脑海中:

当我们分配一个局部变量时,它会进入堆栈.类似地,动态分配会导致变量进入堆.现在,我的问题是,这个变量实际上是在堆栈还是堆上,或者我们只是堆栈和堆中的引用.

例如,

假设我声明了一个变量int i.现在这i是在堆栈上分配的.那么,当我打印地址时i,这将是堆栈中的一个位置?堆的问题也一样.

c memory-management heap-memory stack-memory dynamic-allocation

19
推荐指数
3
解决办法
4万
查看次数

Java堆栈和堆内存管理

我想知道如何在以下程序中分配内存:

public class MemoryClass {

    public static void main(final String[] args) {
        int i = 0;
        MemoryClass memoryClass = new MemoryClass();
        memoryClass.myMethod(memoryClass);
    }

    private void myMethod(final Object obj) {
        int i = 1;
        String s = "HelloWorld!";

    }

}
Run Code Online (Sandbox Code Playgroud)

现在,据我所知,下图描述了内存分配的发生方式:
基本运行时内存分配


在上图中,堆栈存储器中的内存,objs实际上是对它们放置在堆内存中的" 实际对象 " 的引用.
以下是我想到的一系列问题:

  1. 哪里的方法小号存储?
  2. 如果我创建了另一个MemoryClass内部对象myMethod,JVM会在堆栈内存中再次为相同的方法分配内存吗?
  3. JVM myMethod是否会在执行完成后立即释放分配的内存,如果是,它将如何管理问题2中提到的情况(仅当JVM多次为同一方法分配内存时才适用).
  4. 如果我只声明了s并且没有初始化它,那么JVM是否仍会为所有java.lang.String类的方法分配内存,如果是这样,为什么呢?

java memory memory-management heap-memory stack-memory

19
推荐指数
2
解决办法
1万
查看次数

为什么允许 std::initializer_list 不指定大小并同时分配堆栈?

我从这里了解到不需要std::initializer_list分配堆内存。这对我来说很奇怪,因为您可以在不指定大小的情况下获取std::initializer_list对象,而对于数组,您始终需要指定大小。尽管初始化器列表在内部几乎与数组相同(正如帖子所暗示的那样)。

我很难理解的是,C++ 作为静态类型语言,每个对象的内存布局(和大小)必须在编译时固定。因此,每个std::array都是另一种类型,我们只是从通用模板中生成这些类型。但对于std::initializer_list,此规则显然不适用,因为接收函数或构造函数不需要考虑内存布局(虽然它可以从传递给其构造函数的参数派生)。仅当类型堆分配内存并且仅保留存储来管理该内存时,这对我才有意义。那么差异就很像std::arrayand std::vector,对于后者,您也不需要指定大小。

std::initializer_list不使用堆分配,正如我的测试所示:

#include <string>
#include <iostream>

void* operator new(size_t size)
{
    std::cout << "new overload called" << std::endl;    
    return malloc(size);
}


template <typename T>
void foo(std::initializer_list<T> args)
{
    for (auto&& a : args)
    std::cout << a << std::endl;
}

int main()
{
    foo({2, 3, 2, 6, 7});

    // std::string test_alloc = "some string longer than std::string SSO";
} …
Run Code Online (Sandbox Code Playgroud)

c++ types heap-memory stack-memory stdinitializerlist

19
推荐指数
3
解决办法
1966
查看次数

在java中的堆栈内存上创建对象?

出于好奇,这只是一个简单的理论问题.我一直都喜欢java风扇男孩.但有一件事让我想知道为什么java不提供在堆栈上创建对象的机制?如果我可以在堆栈而不是堆上创建小的Point(int x,int y)对象,就像在C#上创建结构一样,那会不会更有效率.在java中这个限制背后有什么特殊的安全原因吗?:)

java value-type stack-memory

14
推荐指数
2
解决办法
4507
查看次数

如何管理,实现和分配堆和堆栈内存?

在C/C++中,我们可以在堆栈或堆上存储变量,函数,成员函数,类的实例.

每个如何实施?如何管理(高级别)?gcc是否预先分配了一大块内存用于堆栈和堆,然后根据请求发送?原始内存来自RAM吗?

可以在堆而不是堆栈上分配函数吗?

澄清

我真的在询问堆和堆栈存储器的实现和管理.在阅读引用的问题后,我找不到任何解决这个问题的方法......感谢链接

c++ memory-management heap-memory stack-memory

12
推荐指数
2
解决办法
4483
查看次数

为什么 Rust 中的字符串文字是 &amp;str 而不是 String?

我只是问为什么 Rust 决定使用&str字符串文字而不是String. Rust 是不是可以自动将字符串文字转换为 aString并将其放在堆中而不是将其放入堆栈中?

string heap-memory string-literals stack-memory rust

12
推荐指数
2
解决办法
746
查看次数