c++中的删除和Java中的垃圾收集
Delete in C++ and garbage collection in Java
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个部分:
- 程序计数器(由线程使用)
- 虚拟机堆栈(存储主要变量等)
- 本地方法are(OS方法)
- 方法是(包含运行时常量池)
- 堆! !(GC主要在这里工作)
在JVM中,JVM堆中主要有三个部分:
- 伊甸园或年轻代(用于存储最新创建的对象)
- 永久(旧)代(用于存储一些经常使用的对象)
- 永久代(在Jdk 8版本之后合并到老一代)无论如何,希望你对java堆有一些了解,如果没有,你现在应该创建和存储大多数对象。
GC如何工作:第一个用户创建一个对象
0有一个地址并存储在堆中(通常对象有8个字节用于识别,如类信息),一开始,它存储在年轻代中,年轻代中有两个寄存器调用"from"answers"to",它们是相同的。我们现在有0,这个对象有一个计数器,我们创建它的计数器是1,下次使用时,计数器变为2,当计数器改变年轻一代将擦除其他对象(未激活的对象),0将被存储在"from"中,下一次寄存器中的对象"from"将被复制到"to",直到计数器增加到8,它将被复制到第一代
- 老一代采用标记擦除算法。这个过程的第一步被称为标记。这是垃圾收集器识别哪些内存正在使用,哪些没有使用的地方。第二种是普通删除,普通删除删除未引用的对象,留下引用的对象和指向空闲空间的指针。为了进一步提高性能,除了删除未引用的对象外,还可以压缩剩余的引用对象。通过将引用对象移动到一起,这使得新的内存分配更加容易和快速。到目前为止,堆使用这种策略,它可以清理内存并保留始终使用的对象。
欢迎任何建议并感谢,希望它能帮助你理解
- 将数组的地址分配给变量并删除
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- C/C++编译器通常会删除重复的库吗
- 从链接列表c++中删除一个项目
- C++如何通过用户输入删除列表元素
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 是否需要删除包含对象的"pair"?
- 如何在自删除后将对象设置为nullptr
- 迭代时从向量和内存中删除对象
- 使用函数"remove"删除重复元素
- 如何从多映射中删除特定的重复项
- 运算符C++ "delete []"仅删除 2 个前值
- 删除指向指针的指针是运行时错误吗
- 将指针设置为"nullptr"并不能防止双重删除?
- 为什么示例代码访问IUnknown中已删除的内存
- 如何通过 getter 函数删除矢量的元素?
- 从控制台中删除最后打印的元素
- C++中的线程安全删除
- 如何从存储在std::映射中的std::集中删除元素
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数