JVM怎么清理栈中的引用 JVM的垃圾回收机制什么时候清理栈中对象引用我知道它在需要的时候会自动清理堆中的对象所占的空间,但栈中的对象引用虽不占多少空间但存在也确实浪费资源,系统什么时候清理?怎么清理?栈是先进后出的,如果垃圾是在非垃圾的下面,这块垃圾什么时候清理? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 栈不归gc管.gc只处理堆中的数据.如果学过汇编语言或者危机原理的话应该知道栈是如何处理的,java的线程栈和这个类似. 一般在CPU相对空闲的时候清理垃圾的 JAVA实现的栈和其它语言的栈有很大的区别。JAVA虚拟机的所有所有运算是基于栈结构,其它真实的机器是基于寄存器的。JAVA中所有对象空间都是动态分配的。分配对象空间可以全部在堆中分配,也可以全部在栈中分配,或者有的在堆中,有的要栈中。取决于具体的虚拟机实现。所以,所谓的栈中的对象其实和堆中的对象没有什么区别。 俺个人理解是局部变量引用, 自动清理.一般的对象都是在堆上保存的吧. 虚拟机肯定内部保存了一套对象的真实地址,也保存了程序的变量和地址的映射表,如果映射表中的对象无效,表明这个变是=NULL了 所以当GC的时候就从真实地址中调用 free(p*) 真正释放内存. 垃圾回收机制(内部机理 )垃圾回收的算法有很多,不过怎么样,任何一个算法都要做两件事情,一是识别垃圾对象,二是清理内存以备运行程序使用。区分活着的对象和垃圾对象的主要方法就是参考计数和追踪,参考计数就是每个对象都维护一个引用 count,而每次追踪都去标记对象,当一次跟踪完成没有被标记的对象就是不可到达的那就是垃圾了。参考计数的方式现在已经很少JVM实现用了,因为对于 child, parent 的内部参考,count 永远不会是0,也就是不会是垃圾对象,而且每次修改引用都要加减 count。而跟踪是从根节点开始扫描所有对象,并作标记。知道那些对象是垃圾了之后,就要释放了,有两种方式一个是压缩,一个是拷贝,不管哪种方式改变了对象的物理位置,就要修改他的参考值,每个对像都有一个 finalize 方法,一般我们不去 override 他,他是在回收时期执行,但并不是所有的对象的 finalize 方法都会被执行 栈中的数据你不用考虑,这是由栈数据结构决定的,生命结束自动清除Java 的操作是基于栈的,而是基于寄存器的,一个简单的道理,如果栈中的数据得不到自动清理,那么程序是无法继续执行了 栈顶指针依次向栈底移动,当前栈顶的数据就认为不在栈里了。我给楼主举个例子吧(多给分哦,呵呵)class Collar{}class Dog{ Clollar c; String name; public static void main(String[] args){ Dog d; d=new Dog(); d.go(d); } void go(Dog dog){ c= new Collar(); dogs.setName("Aiko"); } void setName(String dogName){ name = dogName; }}下面解释,代码在后台,堆和栈的存储及清楚方式: 首先:在第7行:将main()置于栈上第9行:在栈上创建引用变量d,但Dog对象尚不存在,第10行:创建新的Dog对象,并将其赋予d引用变量。第11行:将引用d的一个副本传递给go()方法第13行:将go()方法置于栈上,并将dog参数作为局部变量第14行:在堆上创建新的Collar对象,并将其赋予Dog的实例变量第17行:将setName()添加到栈上,并将dogName参数作为其局部变量。第18行:name实例变量现在也引用String 对象。注意:两个不同的局部变量引用相同的Dog对象。一个局部变量和一个实例变量都引用相同的String Aiko第19行执行完之后(name=dogName;这句)将会完成并从栈中清除。此时局部变量dogName也会消失,尽管它引用的String 对象仍在堆上下面把栈的存储说下:从栈顶到栈底依次为:setName() dogNamego() dogmain() d堆的图不好画,显示不出来就省略了! 不是把方法放在栈上,而是创建一个方法的frame,供当前的方法使用。参考一下编译原理 finalize() 自动回收!!至于什么时候回收,我们一般不会关注这个问题,一般的在CPU相对空闲或者资源不够的情况下,其会回收!! java中时间奇怪的问题,急。。。。 一个关于转译字符的问题 一个数据库事物操作问题 一些问题! window.open()自身覆盖自身页面 如何在JFrame被关闭的时候让它执行另外一段代码后再关闭 简单的问题 我的JB老出错,请帮忙看看,一定加分 print输出宽度有规定,左对齐,不足补空格,怎么做啊? 各位大虾!求救!!有一个关于调用输入类的程序,有一个错误,请指教!! 字符串排序 gc
gc只处理堆中的数据.
如果学过汇编语言或者危机原理的话应该知道栈是如何处理的,java的线程栈和这个类似.
一般的对象都是在堆上保存的吧. 虚拟机肯定内部保存了一套对象的真实地址,也保存了程序的变量和地址的映射表,
如果映射表中的对象无效,表明这个变是=NULL了 所以当GC的时候就从真实地址中调用 free(p*) 真正释放内存.
(内部机理 )垃圾回收的算法有很多,不过怎么样,任何一个算法都要做两件事情,一是识别垃圾对象,二是清理内存以备运行程序使用。区分活着的对象和垃圾对象的主要方法就是参考计数和追踪,参考计数就是每个对象都维护一个引用 count,而每次追踪都去标记对象,当一次跟踪完成没有被标记的对象就是不可到达的那就是垃圾了。参考计数的方式现在已经很少JVM实现用了,因为对于 child, parent 的内部参考,count 永远不会是0,也就是不会是垃圾对象,而且每次修改引用都要加减 count。而跟踪是从根节点开始扫描所有对象,并作标记。知道那些对象是垃圾了之后,就要释放了,有两种方式一个是压缩,一个是拷贝,不管哪种方式改变了对象的物理位置,就要修改他的参考值,每个对像都有一个 finalize 方法,一般我们不去 override 他,他是在回收时期执行,但并不是所有的对象的 finalize 方法都会被执行
我给楼主举个例子吧(多给分哦,呵呵)class Collar{}class Dog{
Clollar c;
String name; public static void main(String[] args){
Dog d;
d=new Dog();
d.go(d);
} void go(Dog dog){
c= new Collar();
dogs.setName("Aiko");
} void setName(String dogName){
name = dogName;
}}
下面解释,代码在后台,堆和栈的存储及清楚方式:
在第7行:将main()置于栈上
第9行:在栈上创建引用变量d,但Dog对象尚不存在,
第10行:创建新的Dog对象,并将其赋予d引用变量。
第11行:将引用d的一个副本传递给go()方法
第13行:将go()方法置于栈上,并将dog参数作为局部变量
第14行:在堆上创建新的Collar对象,并将其赋予Dog的实例变量
第17行:将setName()添加到栈上,并将dogName参数作为其局部变量。
第18行:name实例变量现在也引用String 对象。注意:两个不同的局部变量引用相同的Dog对象。
一个局部变量和一个实例变量都引用相同的String Aiko第19行执行完之后(name=dogName;这句)将会完成并从栈中清除。
此时局部变量dogName也会消失,尽管它引用的String 对象仍在堆上下面把栈的存储说下:
从栈顶到栈底依次为:
setName() dogName
go() dog
main() d
堆的图不好画,显示不出来就省略了!
参考一下编译原理
至于什么时候回收,我们一般不会关注这个问题,一般的在CPU相对空闲或者资源不够的情况下,其会回收!!