在Java和C中返回引用/地址的区别
Java和C语言中返回引用或地址的问题是因为对象在Java中由垃圾回收器进行管理,而在C语言中需要手动释放内存。在Java中,一个对象只有在没有任何活动线程或静态引用引用它时才可以进行垃圾回收。换句话说,如果一个对象的所有引用都为null,那么它就可以进行垃圾回收。循环依赖不计算为引用,所以如果对象A引用对象B,对象B引用对象A,并且它们没有其他活动引用,那么对象A和B都可以进行垃圾回收。
Java中的对象在堆中创建,堆被分为三个部分或代用于垃圾回收,分别称为新生代、老年代和永久代。新生代又被进一步分为三个部分,称为Eden空间、Survivor 1和Survivor 2空间。当对象首次在堆中创建时,它被创建在新生代的Eden空间中,经过次要垃圾回收后,如果一个对象存活下来,它会被移动到Survivor 1,然后再移到Survivor 2,最后在主要垃圾回收时将该对象移动到老年代。
Java堆的永久代用于存储有关类和方法的元数据、字符串池和类级别的详细信息。
虽然可以使用System.gc()或Runtime.gc()方法请求JVM运行垃圾回收,但不能强制JVM运行垃圾回收。
标记-清除算法是最常用的垃圾回收算法之一。任何垃圾回收算法都必须执行两个基本操作。首先,它必须能够检测所有不可达对象;其次,它必须回收垃圾对象所使用的堆空间,并将该空间重新提供给程序使用。标记-清除算法通过两个阶段来执行上述操作:标记阶段和清除阶段。
以上是关于Java和C语言中返回引用或地址的问题以及解决方法的内容。
在Java中,垃圾回收(Garbage Collection)是自动运行的,它会释放程序不再使用的对象所占用的内存空间。例如,在下面的代码中:
public static Object otherMethod(Object obj) { return new Object(); } public static void main(String[] args) { Object myObj = new Object(); myObj = otherMethod(myObj); // ... more code ... }
在调用otherMethod()
之后,原始创建的Object
对象变得不可访问,这就是被垃圾回收的"垃圾"。
虽然Java的垃圾回收是自动运行的,但也可以使用System.gc()
显式地调用它,试图强制进行一次主垃圾回收。但正如Pascal Thivent所指出的,你真的不应该这样做,这可能会带来更多的伤害(参见这个问题)。
更多信息,请参阅维基百科关于垃圾回收和Oracle的调整垃圾回收。
据我所知,System.gc()
并不能强制运行垃圾回收。
赞一个好的代码示例。请注意,在调用otherMethod
之前,GC完全可以在此之前销毁myObj
,因为myObj
在那个时候已经不可访问了。
我认为这是实现特定的。
我认为不应该调用System.gc()
,使用GC的整个目的就是不需要这样做。
通过逃逸分析(en.wikipedia.org/wiki/Escape_analysis),在这个例子中JVM可能根本就不会分配对象。整个对象的创建(理论上)可以被优化掉。当然,这取决于具体的实现。
在Java中,垃圾收集器是Java虚拟机上运行的程序,它会清除Java应用程序不再使用的对象。它是一种自动内存管理的形式。
当一个典型的Java应用程序运行时,它会创建新的对象,比如字符串和文件,但是在一段时间后,这些对象不再使用。例如,看下面的代码:
for (File f : files) { String s = f.getName(); }
在上面的代码中,每次循环迭代都会创建一个新的字符串对象。这意味着在每次迭代中,都会分配一小部分内存来创建一个字符串对象。
回到代码,我们可以看到一旦执行了一个迭代,在下一次迭代中,之前创建的字符串对象就不再被使用了 -- 这个对象现在被认为是“垃圾”。
最终,我们会开始积累大量的垃圾,内存将被用于不再使用的对象。如果这种情况持续下去,最终Java虚拟机将无法再为新对象分配空间。
这就是垃圾收集器的作用。
垃圾收集器会查找不再使用的对象,并将它们清除,释放内存,以便其他新对象可以使用该内存空间。
在Java中,内存管理由垃圾收集器处理,但在其他语言(如C)中,需要使用malloc和free等函数来进行内存管理。内存管理是一种容易出错的事情,可能会导致所谓的内存泄漏 -- 在不再使用时没有回收内存。
像垃圾收集这样的自动内存管理方案使得程序员不必过多担心内存管理问题,可以更专注于开发他们需要开发的应用程序。
在Java应用程序运行在计算机上时,是否可以说它有两个垃圾收集功能,一个是在Java虚拟机上,另一个是在运行Windows(或其他操作系统)的实际机器上?
不,通常只有在JRE存在时才能运行Java应用程序。所以,只需要JVM的垃圾收集功能!