首页 > 电子产品 > 知识 > gc回收,线程会不会被gc回收

gc回收,线程会不会被gc回收

来源:整理 时间:2023-12-02 23:05:18 编辑:皮来回收 手机版

本文目录一览

1,线程会不会被gc回收

线程也会被回收啊。一般只要是不可用不可达的内存地址对象都可以被回收
这个如果没有引用activity的对象就可以被gc回收,否则,不会

线程会不会被gc回收

2,Java中GC是什么 为什么要有GC

垃圾回收 gc 管理对象和一些不用的东西的回收。保证不会占用太多资源。
GC 是垃圾回收机制。 就是把一些不用内存或者不用的对象销毁后释放空间

Java中GC是什么 为什么要有GC

3,java的gc能立即回收垃圾吗

不一定。现在jvm采用分代回收机制,简单来说就是分为新生代和老生代,老生代内存空间比新生代大;大部分新对象都会优先分配到新生代,当新生代空间满了会发起一次Minor GC。而新分配的大对象或者在新生代空间里存活很久的对象会被放到老生代里,老生代空间满了会发起Major GC,但由于老生代里的对象生命周期比较长加上Major GC速度比Minor GC慢很多,所以发生在老生代的Major GC相对会比Minor GC少很多。因此垃圾能不能被立即回收,要看垃圾的大小,它所处在的空间和当前所处空间是否已满才能基本确定。若想了解得更详细,可以看看《深入理解Java虚拟机:JVM高级特性与最佳实践》这本书。
垃圾回收的缩写就是gc。无论java还是c#的gc都是相应的虚拟机用来释放无用内存的机制,不同之处在于他们用的虚拟机不同。c++的析构函数是程序员手动写的回收内存和善后处理的函数。其功能相当与java的gc(回收内存)和finallize(善后处理)方法加起来。
用finalize方法跟gc可以去回收,但是具有不确定性.如果你要回收的对象里面还有线程在运行,调用system.gc没用,也不会调用你的finalize方法.

java的gc能立即回收垃圾吗

4,如何设置java gc回收算法

在java和c#语言中,使用的是托管代码,不像c++语言那样由程序员进行内存的手动分配和回收,java语言则由JVM即Java虚拟机 全权负责堆内存的管理,这样子大大减少了程序员的负担,同时一定程度上提高了开发效率和系统稳定性,而常用的GC垃圾回收算法有哪些呢?Java的堆是一个运行时数据区,类的实例(对象)从中分配空间。Java虚拟机(JVM)的堆中储存着正在运行的应用程序所建立的所有对象,这些对象通过new、newarray、anewarray和multianewarray等指令建立,但是它们不需要程序代码来显式地释放。一般来说,堆的是由垃圾回收 来负责的,尽管JVM规范并不要求特殊的垃圾回收技术,甚至根本就不需要垃圾回收,但是由于内存的有限性,JVM在实现的时候都有一个由垃圾回收所管理的堆。垃圾回收是一种动态存储管理技术,它自动地释放不再被程序引用的对象,按照特定的垃圾收集算法来实现资源自动回收的功能。
gc不可怕,可怕的是经常full gc,让整个jvm停止工作进行内存回收常见的几种触发点如下1、持久带满了,就是permanet generation满了会导致full gc,如果gc不成功,那就报out of memory了2、旧生代满了,导致full gc3、新生代向s0和s1转移数据,s0和s1向旧生代转移数据,结果两边的内存设置都比较小,持续出现,会导致full gc4、系统直接system.gc常见的调整方法就是在server和client模式下调整我们的gc策略来满足特定场合的需要。一般情况下不需要做这方面的特别调优,只需要设置好持久带和新生代(s0,s1,eden)、旧生代的内存大小即可。java会自动回收当前的资源,如果有需要就自己调用full gc。

5,如何理解垃圾回收gc

作者:朱克锋1:垃圾回收机制由JVM完全负责,编写者在抛弃对象时不必关系空间回收问题2:JVM的垃圾回收机制对堆空间做实时监测,当发现某对象的引用计数为0时,就将该对象列入待回收系类中并不是马上予以销毁3:某个对象被认定为没有必要存在了,那么它所占用的内存就可以被释放,被回收的内存可以用于后续的再分配,并不是对象被抛弃后就立即被回收,垃圾回收器通常只在有对象要回收且系统需要回收时才运行,因此用户无法知道垃圾回收发生的精确时间4:system,gc()也仅仅是一个回收请求,JVM接受到这个消息后并不是立即做垃圾回收,而只是对几个垃圾回收算法做加权使垃圾回收操作容易发生或提前发生5:当对象即将被销毁时,有时需要做一些善后工作,可以把这些操作写在finalize()方法里(终止器)注:到程序接受时,并非所有收尾模块都会得到调用当指向某个对象的最后一个引用被删除,那么该对象就可以被删除:在对象的无用时可以回收Java的垃圾回收并不能保证内存的耗尽,其只是一个低优先级的后台线程且跟踪可达或者不可达的对象A:当JVM的拦截器调用一个合适对象的finalize()方法时,它会忽略任何由finalize()方法抛出的异常,其它情况下finalize()方法中的异常处理同普遍方法的出来是一样的B:Object对象有一个finalize()方法,由于所有的参数都是从Object类继承而来,因此所有对象有一个finalize()方法C:类可以覆盖finalize()方法,而且和普通的方法覆盖一样,不能降低finalize()方法的访问权限,调用finalize()方法本身不会破坏对象
1.java中finalize()的作用一主要是清理那些对象(并非使用new)获得了一块“特殊”的内存区域。程序员可以用finalize()来操作。 程序员都了解初始化的重要性,但常常会忘记同样也重要的清理工作。毕竟,谁需要清理一个int呢?但在使用程序库时,把一个对象用完后就“弃之不顾”的做法并非总是安全的。当然,java有垃圾回收器负责回收无用对象占据的内存资源。但也有特殊情况:假定你的对象(并非使用new)获得了一块“特殊”的内存区域,由于垃圾回收器只知道释放那些经由new分配的内存,所以它不知道该如何释放该对象的这块“特殊”内存区域,为了应对这种情况,java允许在类中定义一个名为finalize()的方法。它的工作原理“假定”是这样的:一旦垃圾回收器准备好释放对象占用的存储孔家,将首先调用其finalize()的方法。并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。所以要是你打算用finalize(),就能在垃圾回收时刻做一些重要的清理工作。注意这里的finalize()并不是c++里的析构.在c++中,对象一定会被销毁,而在java里的对象却并非总是被垃圾回收(1.对象可能不被垃圾回收;2.垃圾回收并并不等于“析构”)。 2.垃圾回收只与内存有关。也就是说,使用垃圾回收器的唯一原因是为了回收程序不再使用的内存。所以对于与垃圾回收有关的任何行为来说(尤其是finalize()方法),它们也必须同内存及其回收有关。但这是否意味着要是对象中含有其他对象,finalize()就应该明确释放那些对象呢?不,无论对象是如何创建的,垃圾回收器都会负责释放对象占据的所有内存。这就将对finalize()的需求限制到一种特殊情况,即通过某种创建对象方式以外的方式为对象分配了存储空间。不过,java中一切皆为对象,那这种特殊情况是怎么回事呢?由于在分配内存时可能采用了类似c语言中的做法,而非java中的通常做法。这种情况主要发生在使用“本地方法”的情况下,本地方法是一种在java中调用非java代码的方式。在非java代码中,也许会调用c的malloc()函数系列来分配存储空间,而且除非了free()函数 3.垃圾回收如何工作“引用记数(reference counting)”是一种简单但速度很慢的垃圾回收技术。每个对象都含有一个引用记数器,当有引用连接至对象时,引用计数加1。当引用离开作用域或被置为null时,引用计数减1。虽然管理引用记数的开销不大,但需要在整个程序生命周期中持续地开销。垃圾回收器会在含有全部对象的列表上遍历,当发现某个对象的引用计数为0时,就释放其占用的空间。这种方法有个缺陷,如果对象之间存在循环引用,可能会出现“对象应该被回收,但引用计数却不为零”的情况。对垃圾回收器而言,定位这样存在交互引用的对象组所需的工作量极大。引用记数常用来说明垃圾收集的工作方式,似乎从未被应用于任何一种java虚拟机实现中。

6,Java垃圾回收GC在什么时候对什么做了什么

GC在什么时候对什么做了什么? 要回答这个问题,先了解下GC的发展史、jvm运行时数据区的划分、jvm内存分配策略、jvm垃圾收集算法等知识。 先说下jvm运行时数据的划分,粗暴的分可以分为堆区(Heap)和栈区(Stack),但jvm的分法实际上比这复杂得多,大概分为下面几块: 1、程序计数器(Program Conuter Register) 程序计数器是一块较小的内存空间,它是当前线程执行字节码的行号指示器,字节码解释工作器就是通过改变这个计数器的值来选取下一条需要执行的指令。它是线程私有的内存,也是唯一一个没有OOM异常的区域。 2、Java虚拟机栈区(Java Virtual Machine Stacks) 也就是通常所说的栈区,它描述的是Java方法执行的内存模型,每个方法被执行的时候都创建一个栈帧(Stack Frame),用于存储局部变量表、操作数栈、动态链接、方法出口等。每个方法被调用到完成,相当于一个栈帧在虚拟机栈中从入栈到出栈的过程。此区域也是线程私有的内存,可能抛出两种异常:如果线程请求的栈深度大于虚拟机允许的深度将抛出StackOverflowError;如果虚拟机栈可以动态的扩展,扩展到无法动态的申请到足够的内存时会抛出OOM异常。 3、本地方法栈(Native Method Stacks) 本地方法栈与虚拟机栈发挥的作用非常相似,区别就是虚拟机栈为虚拟机执行Java方法,本地方法栈则是为虚拟机使用到的Native方法服务。 4、堆区(Heap) 所有对象实例和数组都在堆区上分配,堆区是GC主要管理的区域。堆区还可以细分为新生代、老年代,新生代还分为一个Eden区和两个Survivor区。此块内存为所有线程共享区域,当堆中没有足够内存完成实例分配时会抛出OOM异常。 5、方法区(Method Area) 方法区也是所有线程共享区,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。GC在这个区域很少出现,这个区域内存回收的目标主要是对常量池的回收和类型的卸载,回收的内存比较少,所以也有称这个区域为永久代(Permanent Generation)的。当方法区无法满足内存分配时抛出OOM异常。 6、运行时常量池(Runtime Constant Pool) 运行时常量池是方法区的一部分,用于存放编译期生成的各种字面量和符号引用。 垃圾收集(Garbage Collection)并不是Java独有的,最早是出现在Lisp语言中,它做的事就是自动管理内存,也就是下面三个问题:1、什么时候回收2、哪些内存需要回收3、如何回收 1、什么时候回收? 上面说到GC经常发生的区域是堆区,堆区还可以细分为新生代、老年代,新生代还分为一个Eden区和两个Survivor区。 1.1 对象优先在Eden中分配,当Eden中没有足够空间时,虚拟机将发生一次Minor GC,因为Java大多数对象都是朝生夕灭,所以Minor GC非常频繁,而且速度也很快; 1.2 Full GC,发生在老年代的GC,当老年代没有足够的空间时即发生Full GC,发生Full GC一般都会有一次Minor GC。大对象直接进入老年代,如很长的字符串数组,虚拟机提供一个-XX:PretenureSizeThreadhold参数,令大于这个参数值的对象直接在老年代中分配,避免在Eden区和两个Survivor区发生大量的内存拷贝; 1.3 发生Minor GC时,虚拟机会检测之前每次晋升到老年代的平均大小是否大于老年代的剩余空间大小,如果大于,则进行一次Full GC,如果小于,则查看HandlePromotionFailure设置是否允许担保失败,如果允许,那只会进行一次Minor GC,如果不允许,则改为进行一次Full GC。 2、哪些内存需要回收 jvm对不可用的对象进行回收,哪些对象是可用的,哪些是不可用的?Java并不是采用引用计数算法来判定对象是否可用,而是采用根搜索算法(GC Root Tracing),当一个对象到GC Roots没有任何引用相连接,用图论的来说就是从GC Roots到这个对象不可达,则证明此对象是不可用的,说明此对象可以被GC。对于这些不可达对象,也不是一下子就被GC,而是至少要经历两次标记过程:如果对象在进行根搜索算法后发现没有与GC Roots相连接的引用链,那它将会第一次标记并且进行一次筛选,筛选条件是此对象有没有必要执行finalize()方法,当对象没有覆盖finalize()方法或者finalize()方法已经被虚拟机调用执行过一次,这两种情况都被视为没有必要执行finalize()方法,对于没有必要执行finalize()方法的将会被GC,对于有必要有必要执行的,对象在finalize()方法中可能会自救,也就是重新与引用链上的任何一个对象建立关联即可。 3、如何回收 选择不同的垃圾收集器,所使用的收集算法也不同。在新生代中,每次垃圾收集都发现有大批对象死去,只有少量存活,则使用复制算法,新生代内存被分为一个较大的Eden区和两个较小的Survivor区,每次只使用Eden区和一个Survivor区,当回收时将Eden区和Survivor还存活着的对象一次性的拷贝到另一个Survivor区上,最后清理掉Eden区和刚才使用过的Survivor区,Eden和Survivor的默认比例是8:1,可以使用-XX:SurvivorRatio来设置该比例。 而老年代中对象存活率高,没有额外的空间对它进行分配担保,必须使用“标记-清理”或“标记-整理”算法。
文章TAG:回收线程会不会gc回收

最近更新

相关文章

电子产品排行榜推荐