当前位置:首页 » 安卓系统 » 安卓中什么时候会触发gc

安卓中什么时候会触发gc

发布时间: 2022-09-05 09:16:28

A. 一次完整的gc流程是什么

JVM堆分为新生代和老年代,大概比例的1:2,其中新生代又分为1个eden区和2个survivor区,大概比例是8:1:1

GC过程:

1、大对象直接进入到老年代。

2、小对象先在eden区分配内存,当eden满了后,触发一次Minor GC,清理eden区域。

3、存活下来的对象进入到survivor区域,年龄+1。

4、当年龄>15(默认)时进入到老年代,当老年代满了后触发一次Full GC。

在正式 Minor GC 前,JVM 会先检查新生代中对象,是比老年代中剩余空间大还是小。为什么要做这样的检查呢?原因很简单,假如 Minor GC 之后 Survivor 区放不下剩余对象,这些对象就要进入到老年代,所以要提前检查老年代是不是够用。这样就有两种情况:

老年代剩余空间大于新生代中的对象大小,那就直接 Minor GC,GC 完 survivor 不够放,老年代也绝对够放。

老年代剩余空间小于新生代中的对象大小,这个时候就要查看是否启用了“老年代空间分配担保规则”,具体来说就是看-XX:-HandlePromotionFailure参数是否设置了(一般都会设置)。

老年代空间分配担保规则是这样的。如果老年代中剩余空间大小,大于历次 Minor GC 之后剩余对象的大小,那就允许进行 Minor GC。因为从概率上来说,以前的放的下,这次的也应该放的下。那就有两种情况:

老年代中剩余空间大小,大于历次 Minor GC 之后剩余对象的大小,进行 Minor GC。

老年代中剩余空间大小,小于历次 Minor GC 之后剩余对象的大小,进行 Full GC,把老年代空出来再检查。

B. 什么情况下会触发minor gc和full gc

当 JVM 无法为一个新的对象分配空间时会触发 Minor GC,比如当 Eden 区满了。所以分配率越高,越频繁执行 Minor GC。
内存池被填满的时候,其中的内容全部会被复制,指针会从0开始跟踪空闲内存。Eden 和 Survivor 区进行了标记和复制操作,取代了经典的标记、扫描、压缩、清理操作。所以 Eden 和 Survivor 区不存在内存碎片。写指针总是停留在所使用内存池的顶部。
执行 Minor GC 操作时,不会影响到永久代。从永久代到年轻代的引用被当成 GC roots,从年轻代到永久代的引用在标记阶段被直接忽略掉。
质疑常规的认知,所有的 Minor GC 都会触发“全世界的暂停(stop-the-world)”,停止应用程序的线程。对于大部分应用程序,停顿导致的延迟都是可以忽略不计的。其中的真相就 是,大部分 Eden 区中的对象都能被认为是垃圾,永远也不会被复制到 Survivor 区或者老年代空间。如果正好相反,Eden 区大部分新生对象不符合 GC 条件,Minor GC 执行时暂停的时间将会长很多。

C. 为什么安卓系统用久了会卡,苹果系统却依然流畅谁能科普下,比较容易懂

苹果系统的设计和体验口碑一直特别好。比如打开控制中心、多任务处理切换,或APP中滚动浏览等都会比安卓更流畅、更灵敏。尽管安卓的动画效果、全面屏手势等已经可以和苹果系统硬扛,但整体视觉效果不如苹果系统。


以上个人浅见,欢迎批评指正。认同我的看法,请点个赞再走,感谢!喜欢我的,请关注我,再次感谢!


D. android 如何停用gc

1、设置环境变量GOGC=off。
2、运行时调用debug.SetGCPercent(-1)。GC理解为android中的垃圾回收,常见触发垃圾回收是计数引用,当引用计数为0时会触发垃圾回收。此时系统并不会回收内存,而是会当作垃圾存放起来,当下次需要的时候,快速使用。关闭GC系统就会彻底回收内存。

E. Android UI卡顿原因及解决办法

渲染机制介绍

为了分析UI卡顿,我们有必要理解一下渲染机制,这套渲染机制适用于绝大部分的屏幕渲染,其中包括Android手机等众多屏幕设备。

渲染的一些重要参数:

屏幕刷新理想的频率(硬件的角度):60Hz

理想的一秒内绘制的帧数,帧率(屏幕刷新的角度):60fps

这两个参数都是理想值,指代的都是同一个概念。实际情况中难免会比它们低。在60fps内,系统会得到发送的VSYNC(垂直刷新/绘制)信号去进行渲染,就会正常地绘制出我们需要的图形界面。Android手机进行绘制的时候,GPU帮助我们将UI组件等计算成纹理Texture和三维图形Polygons,同时会使用OpenGL---会将纹理和Polygons缓存在GPU内存里面。

其中,VSYNC:有两个概念

Refresh Rate:屏幕在一秒时间内刷新屏幕的次数----有硬件的参数决定,比如60HZ,即屏幕每秒刷新60次

Frame Rate:GPU在一秒内绘制操作的帧数,比如:60fps,

基本结论

要达到60fps,就要求:每一帧只能停留16ms。(大概就是1000ms/60 ~= 16ms刷新一次)

内存抖动是因为大量的对象被创建又在短时间内马上被释放。

 瞬间产生大量的对象会严重占用Young Generation的内存区域,当达到阀值,剩余空间不够的时候,也会触发GC。即使每次分配的对象占用了很少的内存,但是他们叠加在一起会增加Heap的压力,从而触发更多其他类型的GC。这个操作有可能会影响到帧率,并使得用户感知到性能问题。

Android里面是一个三级Generation的内存模型,最近分配的对象会存放在Young Generation区域,当这个对象在这个区域停留的时间达到一定程度,它会被移动到Old Generation,最后到Permanent Generation区域。

Android每个16ms就会绘制一次Activity,通过上述的结论我们知道,如果由于一些原因导致了我们的逻辑、CPU耗时、GPU耗时大于16ms( 应用卡顿的根源就在于16ms内不能完成绘制渲染合成过程,16ms需要完成视图树的所有测量、布局、绘制渲染及合成 ),UI就无法完成一次绘制,那么就会造成卡顿。

比如说,在16ms内,发生了频繁的GC:

在第一个16ms内,UI正常地完成了绘制,那么屏幕不会卡顿。

在第二个16ms内,由于某些原因触发了频发的GC,UI无法在16ms内完成绘制,就会卡顿。

UI卡顿外部和内部常见原因

下面总结一些常见的UI卡顿原因:

  1.内存抖动的问题

 2.方法太耗时了(CPU占用)

    1) CPU计算时间,CPU的测量、布局时间

     2)CPU将计算好的Polygons和Texture传递到GPU的时候也需要时间。OpenGL ES API允许数据上传到GPU后可以对数据进行保存,缓存到display list。因此,我们平移等操作一个view是几乎不怎么耗时的 。

    3) GPU进行格栅化

当我们的布局是用的FrameLayout的时候,我们可以把它改成merge,可以避免自己的帧布局和系统的ContentFrameLayout帧布局重叠造成重复计算(measure和layout)。

使用ViewStub:当加载的时候才会占用。不加载的时候就是隐藏的,仅仅占用位置。

CPU优化建议

针对CPU的优化,从减轻加工View对象成Polygons和Texture来下手:

View Hierarchy中包涵了太多的没有用的view,这些view根本就不会显示在屏幕上面,一旦触发测量和布局操作,就会拖累应用的性能表现。那么我们就需要利用工具进行分析。

如何找出里面没用的view呢?或者减少不必要的view嵌套。

我们利用工具:Hierarchy Viewer进行检测,优化思想是:查看自己的布局,层次是否很深以及渲染比较耗时,然后想办法能否减少层级以及优化每一个View的渲染时间。

我们打开APP,然后打开Android Device Monitor,然后切换到Hierarchy Viewer面板。除了看层次结构之外,还可以看到一些耗时的信息:

三个圆点分别代表:测量、布局、绘制三个阶段的性能表现。

1)绿色:渲染的管道阶段,这个视图的渲染速度快于至少一半的其他的视图。

2)黄色:渲染速度比较慢的50%。

3)红色:渲染速度非常慢。

GPU优化建议就是一句话:尽量避免过度绘制(overdraw)

一、背景经常容易造成过度绘制。

手机开发者选项里面找到工具:Debug GPU overdraw,其中,不同颜色代表了绘制了几次:

F. jvm什么时候会触发full gc

full gc是发生在老年代的gc,所有的gc触发都是因为jvm觉得内存紧张了,所以老年代的full gc也不例外。具体的原因有很多,比如空间分配担保中,发生minor gc(新生代中)jvm会检测之前每次晋升到老年代的平均大小是否大于老年代的剩余空间,如果大于则直接进行full gc,不管怎样,触发gc都有一个宗旨:内存紧张了。建议看看深入java虚拟机。

G. Android 接收大量数据如何避免频繁GC

GC会stop the world。会暂停程序的执行,带来延迟的代价。所以在开发中,我们不希望GC的次数过多。
本文将讨论如何在开发中改善各种细节,从而减少GC的次数。
(1)对象不用时最好显式置为 Null
一般而言,为 Null 的对象都会被作为垃圾处理,所以将不用的对象显式地设
为 Null,有利于 GC 收集器判定垃圾,从而提高了 GC 的效率。
(2)尽量少用 System.gc()
此函数建议 JVM进行主 GC,虽然只是建议而非一定,但很多情况下它会触发
主 GC,从而增加主 GC 的频率,也即增加了间歇性停顿的次数。
(3)尽量少用静态变量
静态变量属于全局变量,不会被 GC 回收,它们会一直占用内存。
(4)尽量使用 StringBuffer,而不用 String 来累加字符串
由于 String 是固定长的字符串对象,累加 String 对象时,并非在一个 String对象中扩增,而是重新创建新的 String 对象,如 Str5=Str1+Str2+Str3+Str4,这条语句执行过程中会产生多个垃圾对象,因为对次作“+”操作时都必须创建新的 String 对象,但这些过渡对象对系统来说是没有实际意义的,只会增加更多的垃圾。 避免这种情况可以改用 StringBuffer 来累加字符串,因 StringBuffer是可变长的,它在原有基础上进行扩增,不会产生中间对象
(5)分散对象创建或删除的时间
集中在短时间内大量创建新对象,特别是大对象,会导致突然需要大量内存,JVM 在面临这种情况时,只能进行主 GC,以回收内存或整合内存碎片,从而增加主 GC 的频率。
集中删除对象,道理也是一样的。 它使得突然出现了大量的垃圾对象,空闲空间必然减少,从而大大增加了下一次创建新对象时强制主 GC 的机会。
(6) 尽量少用 finalize 函数
因为它会加大 GC 的工作量, 因此尽量少用finalize 方式回收资源。
(7) 使用软引用类型
如果需要使用经常用到的图片, 可以使用软引用类型, 它可以尽可能将图片保存在内存中, 供程序调用, 而不引起 OutOfMemory。

H. jvm什么时候会触发full gc

除直接调用System.gc外,触发Full GC执行的情况有如下四种。
1. 旧生代空间不足
旧生代空间只有在新生代对象转入及创建为大对象、大数组时才会出现不足的现象,当执行Full GC后空间仍然不足,则抛出如下错误:
java.lang.OutOfMemoryError: Java heap space
为避免以上两种状况引起的FullGC,调优时应尽量做到让对象在Minor GC阶段被回收、让对象在新生代多存活一段时间及不要创建过大的对象及数组。
2. Permanet Generation空间满
PermanetGeneration中存放的为一些class的信息等,当系统中要加载的类、反射的类和调用的方法较多时,Permanet Generation可能会被占满,在未配置为采用CMS GC的情况下会执行Full GC。如果经过Full GC仍然回收不了,那么JVM会抛出如下错误信息:
java.lang.OutOfMemoryError: PermGen space
为避免Perm Gen占满造成Full GC现象,可采用的方法为增大Perm Gen空间或转为使用CMS GC。
3. CMS GC时出现promotion failed和concurrent mode failure
对于采用CMS进行旧生代GC的程序而言,尤其要注意GC日志中是否有promotion failed和concurrent mode failure两种状况,当这两种状况出现时可能会触发Full GC。
promotionfailed是在进行Minor GC时,survivor space放不下、对象只能放入旧生代,而此时旧生代也放不下造成的;concurrent mode failure是在执行CMS GC的过程中同时有对象要放入旧生代,而此时旧生代空间不足造成的。
应对措施为:增大survivorspace、旧生代空间或调低触发并发GC的比率,但在JDK 5.0+、6.0+的版本中有可能会由于JDK的bug29导致CMS在remark完毕后很久才触发sweeping动作。对于这种状况,可通过设置-XX:CMSMaxAbortablePrecleanTime=5(单位为ms)来避免。
4. 统计得到的Minor GC晋升到旧生代的平均大小大于旧生代的剩余空间
这是一个较为复杂的触发情况,Hotspot为了避免由于新生代对象晋升到旧生代导致旧生代空间不足的现象,在进行Minor GC时,做了一个判断,如果之前统计所得到的Minor GC晋升到旧生代的平均大小大于旧生代的剩余空间,那么就直接触发Full GC。
例如程序第一次触发MinorGC后,有6MB的对象晋升到旧生代,那么当下一次Minor GC发生时,首先检查旧生代的剩余空间是否大于6MB,如果小于6MB,则执行Full GC。
当新生代采用PSGC时,方式稍有不同,PS GC是在Minor GC后也会检查,例如上面的例子中第一次Minor GC后,PS GC会检查此时旧生代的剩余空间是否大于6MB,如小于,则触发对旧生代的回收。
除了以上4种状况外,对于使用RMI来进行RPC或管理的Sun JDK应用而言,默认情况下会一小时执行一次Full GC。可通过在启动时通过- java-Dsun.rmi.dgc.client.gcInterval=3600000来设置Full GC执行的间隔时间或通过-XX:+ DisableExplicitGC来禁止RMI调用System.gc。

I. majorgc触发条件

Major GC通常是跟full GC是等价的,收集整个GC堆。但因为HotSpot VM发展了这么多年,外界对各种名词的解读已经完全混乱了,当有人说“major GC”的时候一定要问清楚他想要指的是上面的full GC还是old gen。

最简单的分代式GC策略,按HotSpot VM的serial GC的实现来看,触发条件是:
young GC:当young gen中的eden区分配满的时候触发。注意young GC中有部分存活对象会晋升到old gen,所以young GC后old gen的占用量通常会有所升高。
full GC:当准备要触发一次young GC时,如果发现统计数据说之前young GC的平均晋升大小比目前old gen剩余的空间大,则不会触发young GC而是转为触发full GC(因为HotSpot VM的GC里,除了CMS的concurrent collection之外,其它能收集old gen的GC都会同时收集整个GC堆,包括young gen,所以不需要事先触发一次单独的young GC);或者,如果有perm gen的话,要在perm gen分配空间但已经没有足够空间时,也要触发一次full GC;或者System.gc()、heap mp带GC,默认也是触发full GC。
HotSpot VM里其它非并发GC的触发条件复杂一些,不过大致的原理与上面说的其实一样。
当然也总有例外。Parallel Scavenge(-XX:+UseParallelGC)框架下,默认是在要触发full GC前先执行一次young GC,并且两次GC之间能让应用程序稍微运行一小下,以期降低full GC的暂停时间(因为young GC会尽量清理了young gen的死对象,减少了full GC的工作量)。这是HotSpot VM里的奇葩嗯。

并发GC的触发条件就不太一样。以CMS GC为例,它主要是定时去检查old gen的使用量,当使用量超过了触发比例就会启动一次CMS GC,对old gen做并发收集。

J. android中的GC是什么意思

你指的是这个吗Gabage Collection?垃圾回收,是.net中对内存管理的一种功能。垃圾回收器跟踪并回收托管内存中分配的对象,定期执行垃圾回收以回收分配给没有有效引用的对象的内存。当使用可用内存不能满足内存请求时,GC会自动进行。 在进行垃圾回收时,垃圾回收器回首先搜索内存中的托管对象,然后从托管代码中搜索被引用的对象并标记为有效,接着释放没有被标记为有效的对象并收回内存,最后整理内存将有效对象挪动到一起。

热点内容
linux驱动开发教程 发布:2024-05-17 17:19:52 浏览:500
抖音中秋节视频脚本 发布:2024-05-17 17:19:51 浏览:193
快递柜为什么用安卓系统 发布:2024-05-17 17:17:18 浏览:906
电脑配置光纤接口怎么标注 发布:2024-05-17 17:06:56 浏览:976
如何用方向键控制安卓机 发布:2024-05-17 16:38:11 浏览:198
雨田系统源码 发布:2024-05-17 16:28:06 浏览:586
新手直播脚本 发布:2024-05-17 16:27:25 浏览:847
python双引号单引号 发布:2024-05-17 16:19:31 浏览:948
0xxc语言 发布:2024-05-17 16:17:40 浏览:700
php与java的区别 发布:2024-05-17 16:12:48 浏览:340