锁定老帖子 主题:深入java虚拟机第9章, 垃圾收集(1)
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-01-03
最后修改:2009-03-25
java虚拟机的堆里存放着正在运行的java程序所创建的所有对象。当一个对象不再被程序引用时,它所使用的堆空间可以被回收,以便后续的新对象所使用。垃圾收集器必须能够断定哪些对象是不再被引用的,并且能够把它们所占据的堆空间释放出来。在释放不再被引用的对象的过程中,垃圾收集器运行将要被释放的对象的终结方法(finalizer)。 除了释放不再被引用的对象,垃圾收集器还要处理堆碎片。在一个虚拟内存系统中,增长的堆所需要的额外分页(或交换)空间会影响运行程序的性能。
垃圾收集 垃圾收集算法要做两件事情 1) 检测出垃圾对象 2)回收垃圾对象所使用的堆空间并还给程序
垃圾检测通常通过建立一个根对象的集合并且检查从这些根对象开始的可触及性来实现。如果正在执行的程序可以访问到的根对象和某个对象之前存在引用路径,这个对象就是可触及的。对于程序来说,根对象总是可以访问的。从这个根对象开始,任何可以被触及的对象都被认为是活动对象。无法被触及的对象被认为是垃圾,因为它们不在影响程序的执行。
java虚拟机的根对象集合根据实现而不同,但是总会包含局部变量中的对象引用和栈帧的操作数栈(以及类变量中的对象引用)。另一个根对象的来源是被加载的类的常量池中的对象引用,比如字符串。还有一个来源是传递到本地方法中的,没有被本地方法释放的对象引用。另一个潜在的根对象的来源是,java虚拟机运行时数据区中从垃圾收集器的堆中分配的部分。
区分活动对象和垃圾的两个基本方法是引用计数和跟踪。 引用计数垃圾收集器通过为堆中的每一个对象保存一个计数来区分活动对象和垃圾对象。这个计数记录下了对那个对象的引用次数。 跟踪垃圾收集器实际上追踪从根结点开始的引用图。在追踪中遇上的对象以某种方式打上标记,当追踪结束时,没有被打上标记的对象就是被断定是不可触及的,可以被当作垃圾收集。
//因此当主线程启动一个子线程,并且主线程以以上任何一种方式退出后. 子线程是否继续执行取决于这个线程是用户线程还是守护线程.如果该子线程是用户线程,该子线程会继续执行.
//这里写得有问题 应该是java程序启动一个线程,并且java程序以以上任何一种方式退出后. 在主线程退出,在jvm退出之前.jvm会判断当前的进程. 如果在没有用户进程(有或没有守护线程)的情况下,jvm会退出 该线程是否继续执行取决于这个线程是用户线程还是守护线程.如果该线程是用户线程,该线程会继续执行.
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-01-04
如果主线程意外中断了,他它开启的其它线程,在虚拟机没有结束进程的情况下,是不是永远不会被释放。
|
|
返回顶楼 | |
发表时间:2009-01-04
最后修改:2009-01-04
maoxiaolu2000 写道 如果主线程意外中断了,他它开启的其它线程,在虚拟机没有结束进程的情况下,是不是永远不会被释放。 java程序的退出有两种机制:一种是程序运行完成,自然退出.另一种是抛出异常或者错误退出. 因此当主线程启动一个子线程,并且主线程以以上任何一种方式退出后. 子线程是否继续执行取决于这个线程是用户线程还是守护线程.如果该子线程是用户线程,该子线程会继续执行. 如果该子线程是守护线程,该子线程会终结. |
|
返回顶楼 | |
发表时间:2009-01-04
“如果是守护线程,该子线程会终结. ”
为什么?? |
|
返回顶楼 | |
发表时间:2009-01-04
maoxiaolu2000 写道 如果主线程意外中断了,他它开启的其它线程,在虚拟机没有结束进程的情况下,是不是永远不会被释放。
在主线程退出,在jvm退出之前.jvm会判断当前的进程. 如果在没有用户进程(有或没有守护线程)的情况下,jvm会退出 该线程是否继续执行取决于这个线程是用户线程还是守护线程.如果该线程是用户线程,该线程会继续执行. 如果该线程是守护线程,该线程会释放. |
|
返回顶楼 | |
发表时间:2009-01-04
taga 写道 “如果是守护线程,该子线程会终结. ”
为什么?? 在主线程退出,在jvm退出之前.jvm会判断当前的进程. 如果在没有用户进程(有或没有守护线程)的情况下,jvm会退出 该线程是否继续执行取决于这个线程是用户线程还是守护线程.如果该线程是用户线程,该线程会继续执行. 如果该线程是守护线程,该线程会释放. |
|
返回顶楼 | |
浏览 4307 次