简体   繁体   English

堆栈框架问题:Java 与 C++

[英]Stack Frame Question: Java vs C++

Q1.一季度。 In Java, all objects, arrays and class variables are stored on the heap?在Java中,所有的对象、数组和类变量都存储在堆上? Is the same true for C++? C++ 也是如此吗? Is data segment a part of Heap?数据段是堆的一部分吗?

What about the following code in C++?下面的 C++ 代码怎么样?

class MyClass{
    private:
            static int counter; 
            static int number;
};

MyClass::number = 100;

Q2. Q2。 As far as my understanding goes, variables which are given a specific value by compiler are stored in data segment, and unintialized global and static variables are stored in BSS (Block started by symbol).就我的理解,编译器赋予特定值的变量存储在数据段中,未初始化的全局和静态变量存储在 BSS(由符号开始的块)中。 In this case, MyClass::counter being static is initialized to zero by the compiler and so it is stored at BSS and MyClass::number which is initialized to 100 is stored in the data segment.在这种情况下,静态的 MyClass::counter 被编译器初始化为零,因此它存储在 BSS 中,而初始化为 100 的 MyClass::number 存储在数据段中。 Am I correct in making the conclusion?我的结论正确吗?

Q3. Q3。 Consider following piece of codes:考虑以下代码:

void doHello(MyClass &localObj){   
// 3.1 localObj is a reference parameter, where will this get stored in Heap or Stack?
      // do something
}

void doHelloAgain(MyClass localObj){   
// 3.2 localObj is a parameter, where will this get stored in Heap or Stack?
      // do something
}

int main(){
      MyClass *a = new MyClass();  // stored in heap

      MyClass localObj;   
      // 3.3 Where is this stored in heap or stack?
      doHello(localObj);
      doHelloAgain(localObj);
}

I hope I have made my questions clear to all我希望我已经向所有人说明了我的问题

EDIT:编辑:

Please refer this article for some understanding on BSS请参考这篇文章对 BSS 有一些了解

EDIT1: Changed the class name from MyInstance to MyClass as it was a poor name. EDIT1:将类名从 MyInstance 更改为 MyClass,因为它是一个糟糕的名称。 Sincere Apologies诚挚的道歉

EDIT2: Changed the class member variable number from non-static to static EDIT2:将类成员变量编号从非静态更改为静态

This is somewhat simplified but mostly accurate to the best of my knowledge.这有点简化,但据我所知,大部分都是准确的。

In Java, all objects are allocated on the heap (including all your member variables).在 Java 中,所有对象都在堆上分配(包括所有成员变量)。 Most other stuff (parameters) are references, and the references themselves are stored on the stack along with native types (ints, longs, etc) except string which is more of an object than a native type.大多数其他东西(参数)是引用,引用本身与本机类型(整数、长整数等)一起存储在堆栈中,除了字符串,它更像是一个对象而不是本机类型。

In C++, if you were to allocate all objects with the "new" keyword it would be pretty much the same situation as java, but there is one unique case in C++ because you can allocate objects on the stack instead (you don't always have to use "new").在 C++ 中,如果要使用“new”关键字分配所有对象,它的情况与 java 几乎相同,但在 C++ 中有一种独特的情况,因为您可以改为在堆栈上分配对象(您并不总是必须使用“新”)。

Also note that Java's heap performance is closer to C's stack performance than C's heap performance, the garbage collector does some pretty smart stuff.还要注意,Java 的堆性能比 C 的堆性能更接近 C 的堆栈性能,垃圾收集器做了一些非常聪明的事情。 It's still not quite as good as stack, but much better than a heap.它仍然不如堆栈好,但比堆好得多。 This is necessary since Java can't allocate objects on the stack.这是必要的,因为 Java 无法在堆栈上分配对象。

Q1第一季度

Java also stores variables on the stack but class instances are allocated on the heap. Java 还在堆栈上存储变量,但在堆上分配类实例。 In C++ you are free to allocate your class instances either on the stack or on the heap.在 C++ 中,您可以在堆栈或堆上自由分配类实例。 By using the new keyword you allocate the instance on the heap.通过使用new关键字,您可以在堆上分配实例。

The data segment is not part of the heap, but is allocated when the process starts.数据段不是堆的一部分,而是在进程启动时分配的。 The heap is used for dynamic memory allocations while the data segment is static and the contents is known at compile time.堆用于动态内存分配,而数据段是静态的并且内容在编译时是已知的。

The BSS segment is simply an optimization where all the data belongning to the data segment (eg string, constant numbers etc.) that are not initialized or initialized to zero are moved to the BSS segment. BSS 段只是一种优化,其中所有属于数据段(例如字符串、常量等)的未初始化或初始化为零的数据都移动到 BSS 段。 The data segment has to be embedded into the executable and by moveing "all the zeros" to the end they can be removed from the executable.数据段必须嵌入到可执行文件中,通过将“所有零”移动到末尾,它们可以从可执行文件中删除。 When the executable is loaded the BSS segment is allocated and initialized to zero, and the compiler is still able to know the addresses of the various buffers, variables etc. inside the BSS segment.当加载可执行文件时,BSS 段被分配并初始化为零,编译器仍然能够知道 BSS 段内的各种缓冲区、变量等的地址。

Q2 Q2

MyClass::number is stored where the instance of MyClass class is allocated. MyClass::number存储在分配MyClass类的实例的位置。 It could be either on the heap or on the stack.它可以在堆上,也可以在堆栈上。 Notice in Q3 how a points to an instance of MyClass allocated on the heap while localObj is allocated on the stack.注意在 Q3 中a如何指向在堆上分配的MyClass的实例,而localObj是在堆栈上分配的。 Thus a->number is located on the heap while localObj.number is located on the stack.因此a->number位于堆上,而localObj.number位于堆栈上。

As MyClass::number is an instance variable you cannot assign it like this:由于MyClass::number是一个实例变量,您不能像这样分配它:

MyClass::number = 100;

However, you can assign MyClass::counter as it is static (except that it is private):但是,您可以分配MyClass::counter因为它是静态的(除了它是私有的):

MyClass::counter = 100;

Q3 Q3

When you call doHello the variable localObj (in main ) is passed by reference.当您调用doHello ,变量localObj (在main )是通过引用传递的。 The variable localObj in doHello refers back to that variable on the stack.变量localObjdoHello指回堆栈变量。 If you change it the changes will be stored on the stack where localObj in main is allocated.如果您更改它,则更改将存储在分配main中的localObj的堆栈中。

When you call doHelloAgain the variable localObj (in main ) is copied onto the stack.当您调用doHelloAgain ,变量localObj (在main )被复制到堆栈中。 Inside doHelloAgain the variable localObj is allocated on the stack and only exists for the duration of the call.doHelloAgain内部,变量localObj分配在堆栈上,并且仅在调用期间存在。

Q1.一季度。 In Java, all objects, arrays and class variables are stored on the heap?在Java中,所有的对象、数组和类变量都存储在堆上? Is the same true for C++? C++ 也是如此吗? Is data segment a part of Heap?数据段是堆的一部分吗?

No, the data section is separate from the heap.不,数据部分与堆分开。 Basically, the data section is allocated at load time, everything there has a fixed location after that.基本上,数据部分是在加载时分配的,之后的所有内容都有一个固定的位置。 In addition, objects can be allocated on the stack.此外,可以在堆栈上分配对象。

The only time objects are on the heap is if you use the new keyword, or if you use something from the malloc family of functions.对象位于堆上的唯一时间是使用new关键字,或者使用malloc系列函数中的某些内容。

Q2. Q2。 As far as my understanding goes, variables which are given a specific value by compiler are stored in data segment, and unintialized global and static variables are stored in BSS (Block started by symbol).就我的理解,编译器赋予特定值的变量存储在数据段中,未初始化的全局和静态变量存储在 BSS(由符号开始的块)中。 In this case, MyInstance::counter being static is initialized to zero by the compiler and so it is stored at BSS and MyInstance::number which is initialized to 100 is stored in the data segment.在这种情况下,静态的 MyInstance::counter 被编译器初始化为零,因此它存储在 BSS 中,而初始化为 100 的 MyInstance::number 存储在数据段中。 Am I correct in making the conclusion?我的结论正确吗?

Yes, your understanding of the BSS section is correct.是的,您对 BSS 部分的理解是正确的。 However, since number isn't static the code:但是,由于number不是静态的代码:

MyInstance::number = 100;

isn't legal, it needs to be either made static or initialized in the constructor properly.不合法,它需要在构造函数中正确设置为静态或初始化。 If you initialize it in the constructor, it will exist wherever the owning object is allocated.如果在构造函数中初始化它,它就会存在于分配拥有对象的任何地方。 If you make it static, it will end up in the data section... if anywhere.如果您将其设为静态,它将最终出现在数据部分......如果在任何地方。 Often static const int variables can be inlined directly into the code used such that a global variable isn't needed at all.通常static const int变量可以直接内联到所使用的代码中,这样根本不需要全局变量。

Q3. Q3。 Consider following piece of codes: ...考虑以下代码:...

void doHello(MyInstance &localObj){

localObj is a reference to the passed object. localObj 是对传递对象的引用。 As far as you know, there is no storage, it refers to wherever the variable being passed is.据您所知,没有存储,它指的是传递的变量在哪里。 In reality, under the hood, a pointer may be passed on the stack to facilitate this.实际上,在幕后,可能会在堆栈上传递一个指针以促进这一点。 But The compiler may just as easily optimize that out if it can.但是如果可以的话,编译器也可以很容易地优化它。

void doHelloAgain(MyInstance localObj){

a copy of the passed parameter is placed on the stack.传递的参数的副本放置在堆栈中。

MyInstance localObj;
// 3.3 Where is this stored in heap or stack?

localObj is on the stack. localObj 在堆栈上。

In C++, objects may be allocated on the stack...for example, localObj in your Q3 main routine.在 C++ 中,对象可能会在堆栈上分配……例如,Q3 主例程中的 localObj。

I sense some confusion about classes versus instances.我感觉到一些关于类与实例的混淆。 "MyInstance" makes more sense as a variable name than a class name. “MyInstance”作为变量名比作为类名更有意义。 In your Q1 example, "number" is present in each object of type MyInstance.在您的 Q1 示例中,“数字”存在于 MyInstance 类型的每个对象中。 "counter" is shared by all instances. “计数器”由所有实例共享。 "MyInstance::counter = 100" is a valid assignment, but "MyInstance::number = 100" is not, because you haven't specified which object should have its "number" member assigned to. "MyInstance::counter = 100" 是一个有效的赋值,但 "MyInstance::number = 100" 不是,因为你还没有指定应该将它的 "number" 成员分配给哪个对象。

此处列出C++ 中的所有内存区域

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM