在Java中释放分配给对象的内存 在C++中,您可以释放分配给这样的对象的内存: int main(){ string myString("MyString"); string *stringPointer = &myString; cout<<myString<<" "<<*stringPointer; delete stringPointer; cout<<myString; //crash return 0; }
这类似于在C中将指针变量设置为NULL++在Java中释放分配给对象的内存 在C++中,您可以释放分配给这样的对象的内存: int main(){ string myString("MyString"); string *stringPointer = &myString; cout<<myString<<" "<<*stringPointer; delete stringPointer; cout<<myString; //crash return 0; },java,c++,Java,C++,这类似于在C中将指针变量设置为NULL++ pointerVariable = NULL; 为了让BST delete函数在Java中工作,我们需要转到节点的父节点,并将要删除的子节点设置为null。 在C++中是否有一个java语言特性,比如删除,使事情变得更容易? < p>不,java中没有语言特征允许你提前删除特定对象(如Python中的代码> DEL代码)。您需要相信垃圾收集器会完成它的工作。(通常情况下,它做得非常好。) Java的垃圾收集器基于对象可达性(不像CPython那样基于
pointerVariable = NULL;
为了让BST delete函数在Java中工作,我们需要转到节点的父节点,并将要删除的子节点设置为null。
在C++中是否有一个java语言特性,比如删除,使事情变得更容易? < p>不,java中没有语言特征允许你提前删除特定对象(如Python中的代码> DEL<代码>代码)。您需要相信垃圾收集器会完成它的工作。(通常情况下,它做得非常好。) Java的垃圾收集器基于对象可达性(不像CPython那样基于引用计数,不像Boehm GC那样基于内存扫描)。这意味着任何没有活动引用的对象都要接受垃圾收集。引用可以是间接的,但来自死对象和死循环的引用不会刺激车库收集器 一些例子:
class Dummy {
String name;
Dummy other;
Dummy(String name) { this.name = name; }
}
void f1() {
Dummy peter = new Dummy("Peter");
peter.other = new Dummy("Fred");
peter.other.other = new Dummy("Megan");
// None of the objects is eligible for garbage collection since
// "Peter" is live and "Fred" can be reached via "Peter" (therefore
// "Fred" is alive) and "Megan" can be reached via "Fred".
peter.other = null;
// Now the reference to "Fred" is lost which makes him a candidate
// for garbage collection. "Megan" is dead too because the
// reference from the dead object "Fred" does not count.
// As the method returns, all three objects are dead and can be
// collected.
}
void f2() {
Dummy clementine = new Dummy("Clementine");
clementine.other = new Dummy("Charles");
clementine.other.other = new Dummy("Caroline");
clementine.other.other.other = clementine;
// Here we have a cycle of
//
// +--> "Clementine" --> "Charles" --> "Caroline" --+
// | |
// +------------------------------------------------+
//
// and since "Clementine" is live, all three are.
clementine = null;
// Once we loose the reference to "Clementine", the cycle still
// exists (every object is referenced by at least one other object)
// but the cycle is dead. Hence, all three are subject to garbage
// collection.
}
有效使用Java垃圾收集的关键是不要保留任何对您不再需要的对象的引用。在二叉树中,执行以下操作:
this.leftChild = null;
将使整个左子树符合垃圾收集的条件。(也就是说,如果没有其他人保留对其中一个节点的活动引用。)
您很少希望允许垃圾收集器收集活动对象。这可以通过使用。我发现它们唯一有用的地方就是缓存
import java.lang.ref.SoftReference;
class StoryOfMyLife {
private final String story;
private transient SoftReference<String[]> cachedWords;
public StoryOfMyLife(final String story) {
this.story = story;
this.cachedWords = new SoftReference<String[]>(null);
}
public synchronized String getWordN(final int n) {
String[] words = this.cachedWords.get();
if (words == null) {
// Called for the first time or cache was garbage collected.
words = this.story.split("\\s+");
this.cachedWords = new SoftReference<String[]>(words);
}
// Note that we are keeping the cache live for the duration of
// this method by keeping the reference 'words'. Once this
// method returns, the cache becomes subject to garbage
// collection again.
return words[n];
}
}
import java.lang.ref.SoftReference;
MyLife类{
私人最后的弦乐故事;
私有瞬态软参考缓存字;
梅里夫的公共故事(最后的弦乐故事){
这个故事;
this.cachedWords=新的软引用(null);
}
公共同步字符串getWordN(最终整数n){
String[]words=this.cachedWords.get();
if(words==null){
//第一次调用或缓存被垃圾回收。
words=this.story.split(\\s+);
this.cachedWords=新的软参考(文字);
}
//请注意,我们将使缓存在
//此方法通过保留引用“words”。一旦
//方法返回时,缓存将变成垃圾
//再次收集。
返回单词[n];
}
}
在本例中,将长字符串(可能非常昂贵)拆分为单词的操作只会延迟进行,并且结果会被缓存。但是,如果系统内存不足,我们允许对缓存进行垃圾收集,因为我们可以随时重新计算它
您可以在上阅读有关Oracle HotSpot JVM中内置的垃圾收集器的更多信息。Java使用基于可访问性的垃圾收集来管理内存,因此为了释放内存,只需确保它不再可访问即可 很少有Java对象需要及时清理: 即那些管理本地资源的。对它们使用
dispose()
,或
旁注:C++对错误记忆的过敏反应:
- 使用作用域出口进行自动存储(这就是您所使用的)。这是RAII的基础
- 使用
补充delete
new
- 使用
来补充delete[]
new[]
- 使用
补充free
、malloc
和calloc
realloc
删除
,java提供垃圾收集。如果您有一个方法可以在树中搜索可删除的节点,为什么不在那里将该节点设置为null?我的意思是,有没有一种方法可以使对象在仍有引用的情况下符合垃圾收集的条件?(像C++中的删除)是的,这就是“.C++中,你可以释放分配给这样的对象的内存”——不,你不能。只能对通过new
分配的对象使用delete
。您所做的只是调用未定义的行为。
import java.lang.ref.SoftReference;
class StoryOfMyLife {
private final String story;
private transient SoftReference<String[]> cachedWords;
public StoryOfMyLife(final String story) {
this.story = story;
this.cachedWords = new SoftReference<String[]>(null);
}
public synchronized String getWordN(final int n) {
String[] words = this.cachedWords.get();
if (words == null) {
// Called for the first time or cache was garbage collected.
words = this.story.split("\\s+");
this.cachedWords = new SoftReference<String[]>(words);
}
// Note that we are keeping the cache live for the duration of
// this method by keeping the reference 'words'. Once this
// method returns, the cache becomes subject to garbage
// collection again.
return words[n];
}
}