c++中的删除和Java中的垃圾收集

Delete in C++ and garbage collection in Java

本文关键字:删除 c++ Java      更新时间:2023-10-16

c++中的delete是否与Java中的垃圾收集相同?我的意思是,内部的内存管理部分(在这两种情况下堆中究竟发生了什么?)

c++中的delete调用使用new操作符释放变量占用的Free Store (heap)内存。所有这些都是手工完成的(直到我们使用智能指针,c++ 11等等),对于每个new,我们必须做相应的delete操作。垃圾收集器仅在c++ 11及以上版本中存在。其他语言(Java, c#)中的垃圾回收会自动释放变量占用的内存。在后台,垃圾收集器保持变量的引用计数,当引用计数达到0(或变量超出作用域)时,它释放该变量占用的内存。

在c++中,delete, delete[]new操作符的功能可以通过操作符重载来定义,因此您可以使其按照您的意愿工作。

在Java的堆行为是由JVM定义的,一般来说,只要内存中不存在对对象的引用,它最终将被垃圾收集器清除。有关Java垃圾收集的更多细节,请参阅本文。

实际上垃圾收集是自动的。VM会自动这么做。您可以使用System.gc()强制VM进行垃圾收集。

在堆上进行分配和释放。让我们举个例子。在c++ STL容器中,使用一个称为allocator的对象来进行内存管理。它在堆上分配内存(让我们假设它被分配到任何没有被占用的随机位置),然后释放它。现在分配器可以有一个映射,或者一个数组,或者某种数据结构,它可以用它来判断是否有一些内存是空闲的,也就是说,一些内存是它之前分配和释放过的。它可以自己跟踪这个,怎么做是实现定义的。所有程序员和标准都指定它只是这样做(以及其中的一些限制),因此作为程序员,您通常不应该担心堆分配是如何完成的。编译器可以优化代码,使其在不同的情况下表现不同。

现在回到你关于c++中的删除和Java中的垃圾收集的问题。c++编译成原始的机器可执行代码,即由机器本机运行的代码(汇编代码),而Java编译成"字节码","字节码"由Java虚拟机(JVM)执行,它本身就是一个程序。c++中的delete使机器释放堆上的内存。在java中,当对象没有任何引用和垃圾收集发生时,会自动执行删除操作。这里的JVM就像allocator,它"释放"内存。

内存被标记为已释放。它可以被重复使用。在机器级别发生的情况可能会有很大的不同。您甚至可以通过重载操作符来让它们做您想做的事情!希望有帮助

c++中:New和delete用于创建和删除一个"空间"。这个空间主要用来存储你的数据。通常使用堆栈来存储一些返回值,局部变量,函数参数等,堆是另一个通常由程序员创建的空间。然而,还有其他空间,如static,用于存储全局变量和静态值或常量。在C语言中,我们通常使用malloc/free,在c++中我们使用new/delete,你应该知道malloc()只是一个函数,而new()是一个构造函数。

Time *t;
t = new Time(0,0,0,/"t");//this allowed you create a space in heap by using constructor

现在堆中有一个空间,p是指向这个地址的

delete t;// this delete is used to delete the pointer, which means this space won't be used anymore, after a short time, C++ will recycle this space.

JAVA:在java中,您应该了解JVM和GC。JVM有5个部分:

  1. 程序计数器(由线程使用)
  2. 虚拟机堆栈(存储主要变量等)
  3. 本地方法are(OS方法)
  4. 方法是(包含运行时常量池)
  5. 堆! !(GC主要在这里工作)

在JVM中,JVM堆中主要有三个部分:

  • 伊甸园或年轻代(用于存储最新创建的对象)
  • 永久(旧)代(用于存储一些经常使用的对象)
  • 永久代(在Jdk 8版本之后合并到老一代)无论如何,希望你对java堆有一些了解,如果没有,你现在应该创建和存储大多数对象。
  • GC如何工作:第一个用户创建一个对象

  • 0有一个地址并存储在堆中(通常对象有8个字节用于识别,如类信息),一开始,它存储在年轻代中,年轻代中有两个寄存器调用"from"answers"to",它们是相同的。我们现在有0,这个对象有一个计数器,我们创建它的计数器是1,下次使用时,计数器变为2,当计数器改变年轻一代将擦除其他对象(未激活的对象),0将被存储在"from"中,下一次寄存器中的对象"from"将被复制到"to",直到计数器增加到8,它将被复制到第一代

  • 老一代采用标记擦除算法。这个过程的第一步被称为标记。这是垃圾收集器识别哪些内存正在使用,哪些没有使用的地方。第二种是普通删除,普通删除删除未引用的对象,留下引用的对象和指向空闲空间的指针。为了进一步提高性能,除了删除未引用的对象外,还可以压缩剩余的引用对象。通过将引用对象移动到一起,这使得新的内存分配更加容易和快速。到目前为止,堆使用这种策略,它可以清理内存并保留始终使用的对象。

欢迎任何建议并感谢,希望它能帮助你理解