
GC是garbagecollection缩写,翻译过来就是垃圾回收一个跟踪过程,
它传递性地跟踪指向当前使用的对象的所有指针,以便找到可以引用的所有对象,然后重新使用在此跟踪过程中未找到的任何堆内存。公共语言运行库垃圾回收器还压缩使用中的内存,以缩小堆所需要的工作空间。
当程序向 *** 作系统申请的内存不再需要时,垃圾回收主动将其回收并供其他代码进行内存申请时候复用,或者将其归还给 *** 作系统,这种针对内存级别资源的自动回收过程,即为垃圾回收。而负责垃圾回收的程序组件,即为垃圾回收器。垃圾回收其实一个完美的“SimplicityisComplicated”的例子。
一方面,程序员受益于GC,无需 *** 心、也不再需要对内存进行手动的申请和释放 *** 作,GC在程序运行时自动释放残留的内存。另一方面,GC对程序员几乎不可见,仅在程序需要进行特殊优化时,通过提供可调控的API,对GC的运行时机、运行开销进行把控的时候才得以现身。
当内存中的某一个对象无法找到任何引用的时候,这个对象就是一个垃圾对象。
内存泄露(memory leak),是指程序中已动态分配的堆内存由于某种原因程序未将其释放或无法释放,造成了内存的浪费,导致程序运行速度减慢甚至程序崩溃等严重后果。
STW即stop the world ,指的是JVM进行GC时会暂停所有业务线程。
给每一个对象添加一个引用计数器,t每当有新的引用时,计数器+1,引用结束后计数器-1。任何时刻计数器为0的对象都是不被引用的。
优点:
1 引用计数算法在回收垃圾时具有实时性。当一个对象的引用为0的时候会被直接回收,无需等待特定时间就可以释放内存。
缺点:
1当出现对象之间循环引用的时候,垃圾回收期无法确定这些对象是否是垃圾,因此无法回收循环引用的对象。(内存泄漏)
从GC Roots节点(起始节点)出发向下搜索,如果没有任何引用链(既GC root不可达),则证明此对象不可用
tracing GC的本质是通过找出所有活对象来把其余空间认定为“无用”,而不是找出所有死掉的对象并回收它们占用的空间。GC roots这组引用是tracing GC的起点。要实现语义正确的tracing GC,就必须要能完整枚举出所有的GC roots,否则就可能会漏扫描应该存活的对象,导致GC错误回收了这些被漏扫的活对象。
将需要清除的对象标记出来,清除掉。
标记清除算法的实现分为两个阶段:
优点:
只对存活的对象进行标记。标记完毕后再扫描整个空间中未被标记的对象进行回收。该算法不需要进行对象的移动,只需对不存活的对象进行处理,效率高。
缺点
因为直接回收掉了不存活对象,未对内存进行整理,因此会产生内存碎片。内存碎片较多时,当大对象进入内存空间,无法为期分配足够的内存会提前触发GC。
将内存一分为二,每次使用一个区域。当触发gc时,将存活对象复制到另一区域,清除原区域。
它开始时把堆分成 一个对象 面和多个空闲面, 程序从对象面为对象分配空间,当对象满了,基于copying算法的垃圾 收集就从根集合(GC Roots)中扫描活动对象,并将每个 活动对象复制到空闲面(使得活动对象所占的内存之间没有空闲洞),这样空闲面变成了对象面,原来的对象面变成了空闲面,程序会在新的对象面中分配内存。
优点 :
缺点:
标记清除算法的优化实现,清除垃圾对象的同时压缩空间。
该算法标记阶段和Mark-Sweep一样,但是在完成标记之后,它不是直接清理可回收对象,而是将存活对象都向一端移动,然后再清理掉无用对象
优点:
1因为对空间进行了整理,因此不会产生内存碎片。
缺点
1因为扫描了两次,并且在清除的基础上还增加了整理,因此时间成本高。
GC有多层含义,一是计算机术语,指Garbage Collection;二是网络用语,支持的意思;三是网络域中的GC,就是“全局目录”Global Catalog;四是科研用语,即Gas Chromatography(气相色谱法)。
GC(Grid Communication)网格通信。网格是一种新兴的技术,正处在不断发展和变化当中。目前学术界和商业界围绕网格开展的研究有很多,其研究的内容和名称也不尽相同因而网格尚未有精确的定义和内容定位。比如国外媒体常用“下一代互联网”、“Internet2”、“下一代Web”等来称呼网格相关技术。但“下一代互联网(NGI)”和“Internet2”又是美国的两个具体科研项目的名字。
CG在网络方面的应用:
在C/C++程序中,程序员在内存中主动开辟一段相应的空间来存值。由于内存是有限的,所以当程序不再需要使用该内存空间时,就需要销毁对象并释放其所占用的内存资源,好重新利用这段空间。在C/C++中,释放无用内存空间的事情需要由程序员自己来处理。
就是说当程序员认为空间没用了,就手动地释放其占用的内存。但是这样显然非常繁琐,如果有所遗漏,就可能造成资源浪费甚至内存泄露。当软件系统比较复杂,变量多的时候程序员往往就忘记释放内存或者在不该释放的时候释放内存了。
百度百科-GC
实践中我们发现对于大多数的应用领域,评估一个垃圾收集(GC)算法需要如下三个标准:
首先让我们来明确垃圾收集(GC)中的两个术语:
JVM在专门的线程(GC Threads)中执行GC,只要GC线程是活动的,它们将与应用程序线程(application threads)争用当前可用的CPU时钟周期。 简单点来说,吞吐量是指用户应用程序线程用时占程序总用时的比例。 例如,吞吐量99/100意味着100秒的程序执行时间中用户应用程序线程运行了99秒, 而在这段时间内GC线程只运行了1秒。
术语”暂停时间”是指一个时间段内应用程序线程让与GC线程执行而完全暂停。 例如,GC期间100毫秒的暂停时间意味着在这100毫秒期间内没有用户应用程序线程是活动的。 如果说一个正在运行的应用程序有100毫秒的“平均暂停时间”,那么就是说该用户应用程序所有的暂停时间平均长度为100毫秒。 同样,100毫秒的“最大暂停时间”是指该用户应用程序所有的暂停时间最大不超过100毫秒。
1高吞吐量最好,因为这会让应用程序的最终用户感觉只有应用程序线程在做“生产性”工作。 直觉上,吞吐量越高程序运行越快。
2低暂停时间最好,因为从最终用户的角度来看不管是GC还是其他原因导致一个应用被挂起始终是不好的。 这取决于应用程序的类型,有时候甚至短暂的200毫秒暂停都可能打断终端用户体验。 因此,具有低的最大暂停时间是非常重要的,特别是对于一个交互式应用程序。
3不幸的是”高吞吐量”和”低暂停时间”是一对相互竞争的目标(矛盾)。
这样想想看,为了清晰起见简化一下:GC需要一定的前提条件以便安全地运行。 例如,必须保证应用程序线程在GC线程试图确定哪些对象仍然被引用和哪些没有被引用的时候不修改对象的状态。 为此,应用程序在GC期间必须停止(或者仅在GC的特定阶段,这取决于所使用的算法)。 然而这会增加额外的线程调度开销:直接开销是上下文切换,间接开销是因为缓存的影响。 加上JVM内部安全措施的开销,这意味着GC及随之而来的不可忽略的开销,将增加GC线程执行实际工作的时间。 因此我们可以通过尽可能少运行GC来最大化吞吐量,例如,只有在不可避免的时候进行GC,来节省所有与它相关的开销。
然而,仅仅偶尔运行GC意味着每当GC运行时将有许多工作要做,因为在此期间积累在堆中的对象数量很高。 单个GC需要花更多时间来完成, 从而导致更高的平均和最大暂停时间。 因此,考虑到低暂停时间,最好频繁地运行GC以便更快速地完成。 这反过来又增加了开销并导致吞吐量下降,我们又回到了起点。
综上所述,在设计(或使用)GC算法时,我们必须确定我们的目标:一个GC算法只可能针对两个目标之一(即只专注于最大吞吐量或最小暂停时间),或尝试找到一个二者的折衷。
Throughput收集器有两个基本 *** 作:一是回收新生代垃圾(Minor GC);二是回收老年代垃圾(Full GC)。
下图是新生代回收之前和之后的情况
Minor GC通常在新生代空间用尽时。新生代收集器会把Eden空间中的所有对象挪走:一部分被移到Survivor中,其它被移到老年代。
下图是Full gc之前之后的对比图
老年代垃圾收集会收集新生代中所有的对象(包括Survivor中的对象),只有那些有活跃引用的对象,或者已经经过压缩整理的对象会继续在老年代中留存下来。其余对象将被回收。
Throughput收集器的调优几乎都是围绕停顿时间进行的,寻求堆的总体大小、新生代的大小以及老年代大小之间的平衡 。
两种取舍:
1、经典技术上的取舍,时间和空间上的取舍;
2、第二个取舍与完成垃圾回收所需的时长有关,增大堆能够减少Full GC停顿发送的频率, 但也有局限性:由于GC时间变得更长,平均响应时间也会变长(老年代空间很大,在回收老年代耗时很长)。类似的,为新生代分配更多的堆空间可以缩短Full GC的停顿时间,不过这又增大老年代垃圾回收的频率(因为老年代空间保持不变或者变得更小了)。
看一个示例说明堆大小与吞吐量的关系,在该示例中是关闭了JVM自适应调整堆大小的情况
在Throughput收集器中,可自适应调整会重新分配堆(以及代)的大小。使用这些标志可以设置相应的性能指标:-XX:MaxGCPauseMillis=N和-XX:GCTimeRatio=N。
-XX:MaxGCPauseMillis :标志用于设定应用可承受的最大停顿时间。可以设置为0或者一些非常小的值,譬如50毫秒。请注意,这个标志设定的值同时影响Minor GC和Full GC。如果设置的值非常小,那么应用的老年代最终就会非常小,导致频繁的Full GC(例如,希望程序在50毫秒内完成垃圾回收,这将会触发非常频繁的Full GC,对应用程序的性能而言将是灾难性的。)。因此,设定该值时,尽量保持理性,将该值设定为可达到的合理值。缺省情况下, 不设置该参数。
-XX:GCTimeRatio: 标志可以设置你希望应用程序在垃圾回收上花费多少时间(与应用线程的运行时间相比较)。它是一个百分比,默认值是99。
N值得计算稍微有些复杂。将N值代入下面的公式可以计算理想情况下应用线程的运行时间所占的百分比:
将GCTimeRatio的默认值99代入公式得到099,这意味着应用程序的运行时间占总时间的99%,只有1%的时间消耗在垃圾回收上。
再例如GCTimeRatio=95时,并不是意味使用总时间5%去做垃圾回收;它表示的是最多会使用总时间的194%去做垃圾回收。所以,如果你期望程序工作时间在95%,则需要变换一下公式计算 GCTimeRatio 是一个更容易 *** 作的方法。
对于95%(095)的吞吐量目标,利用该公式计算出的 GCTimeRatio 是19 。
JVM使用这两个标志在堆的初始值(-Xms,-XmX)之间的堆的大小。 MaxGCPauseMillis的优先级别最高: 如果设置了这个值,新生代和老年代会随之进行调整,直到满足对应停顿时间的目标。一旦这个目标达成,堆的总容量就开始逐渐增大,直到运行时间的比率达到设定值。这两个目标都达成后,开始缩减堆大小,尽可能的以最小堆大小来满足这两个目标。
该系列的第五部分我们已经讨论过年轻代的垃圾收集器。 对于年老代,HotSpot虚拟机提供两类垃圾收集算法(除了新的G1垃圾收集算法),第一类算法试图最大限度地提高吞吐量,而第二类算法试图最小化暂停时间。 今天我们的重点是第一类,”面向吞吐量”的垃圾收集算法。
我们希望把重点放在JVM配置参数上,所以我只会简要概述HotSpot提供的面向吞吐量(throughput-oriented)垃圾收集算法。 当年老代中由于缺乏空间导致对象分配失败时会触发垃圾收集器(事实上,”分配”的通常是指从年轻代提升到年老代的对象)。 从所谓的”GC根”(GC roots)开始,搜索堆中的可达对象并将其标记为活着的,之后,垃圾收集器将活着的对象移到年老代的一块无碎片(non-fragmented)内存块中,并标记剩余的内存空间是空闲的。 也就是说,我们不像复制策略那样移到一个不同的堆区域,像年轻代垃圾收集算法所做的那样。 相反地,我们把所有的对象放在一个堆区域中,从而对该堆区域进行碎片整理。 垃圾收集器使用一个或多个线程来执行垃圾收集。 当使用多个线程时,算法的不同步骤被分解,使得每个收集线程大多时候工作在自己的区域而不干扰其他线程。 在垃圾收集期间,所有的应用程序线程暂停,只有垃圾收集完成之后才会重新开始。 现在让我们来看看跟面向吞吐量垃圾收集算法有关的重要JVM配置参数。
我们使用该标志来激活串行垃圾收集器,例如单线程面向吞吐量垃圾收集器。 无论年轻代还是年老代都将只有一个线程执行垃圾收集。 该标志被推荐用于只有单个可用处理器核心的JVM。 在这种情况下,使用多个垃圾收集线程甚至会适得其反,因为这些线程将争用CPU资源,造成同步开销,却从未真正并行运行。
有了这个标志,我们告诉JVM使用多线程并行执行年轻代垃圾收集。 在我看来,Java 6中不应该使用该标志因为-XX:+UseParallelOldGC显然更合适。 需要注意的是Java 7中该情况改变了一点(详见本概述),就是-XX:+UseParallelGC能达到-XX:+UseParallelOldGC一样的效果。
该标志的命名有点不巧,因为”老”听起来像”过时”。 然而,”老”实际上是指年老代,这也解释了为什么-XX:+UseParallelOldGC要优于-XX:+UseParallelGC:除了激活年轻代并行垃圾收集,也激活了年老代并行垃圾收集。 当期望高吞吐量,并且JVM有两个或更多可用处理器核心时,我建议使用该标志。
作为旁注,HotSpot的并行面向吞吐量垃圾收集算法通常称为”吞吐量收集器”,因为它们旨在通过并行执行来提高吞吐量。
通过-XX:ParallelGCThreads=<value>我们可以指定并行垃圾收集的线程数量。 例如,-XX:ParallelGCThreads=6表示每次并行垃圾收集将有6个线程执行。 如果不明确设置该标志,虚拟机将使用基于可用(虚拟)处理器数量计算的默认值。 决定因素是由Java Runtime。availableProcessors()方法的返回值N,如果N<=8,并行垃圾收集器将使用N个垃圾收集线程,如果N>8个可用处理器,垃圾收集线程数量应为3+5N/8。
当JVM独占地使用系统和处理器时使用默认设置更有意义。 但是,如果有多个JVM(或其他耗CPU的系统)在同一台机器上运行,我们应该使用-XX:ParallelGCThreads来减少垃圾收集线程数到一个适当的值。 例如,如果4个以服务器方式运行的JVM同时跑在在一个具有16核处理器的机器上,设置-XX:ParallelGCThreads=4是明智的,它能使不同JVM的垃圾收集器不会相互干扰。
吞吐量垃圾收集器提供了一个有趣的(但常见,至少在现代JVM上)机制以提高垃圾收集配置的用户友好性。 这种机制被看做是HotSpot在Java 5中引入的”人体工程学”概念的一部分。 通过人体工程学,垃圾收集器能将堆大小动态变动像GC设置一样应用到不同的堆区域,只要有证据表明这些变动将能提高GC性能。 “提高GC性能”的确切含义可以由用户通过-XX:GCTimeRatio和-XX:MaxGCPauseMillis(见下文)标记来指定。
重要的是要知道人体工程学是默认激活的。 这很好,因为自适应行为是JVM最大优势之一。 不过,有时我们需要非常清楚对于特定应用什么样的设置是最合适的,在这些情况下,我们可能不希望JVM混乱我们的设置。 每当我们发现处于这种情况时,我们可以考虑通过-XX:-UseAdaptiveSizePolicy停用一些人体工程学。
通过-XX:GCTimeRatio=<value>我们告诉JVM吞吐量要达到的目标值。 更准确地说,-XX:GCTimeRatio=N指定目标应用程序线程的执行时间(与总的程序执行时间)达到N/(N+1)的目标比值。 例如,通过-XX:GCTimeRatio=9我们要求应用程序线程在整个执行时间中至少9/10是活动的(因此,GC线程占用其余1/10)。 基于运行时的测量,JVM将会尝试修改堆和GC设置以期达到目标吞吐量。 -XX:GCTimeRatio的默认值是99,也就是说,应用程序线程应该运行至少99%的总执行时间。
通过-XX:GCTimeRatio=<value>告诉JVM最大暂停时间的目标值(以毫秒为单位)。 在运行时,吞吐量收集器计算在暂停期间观察到的统计数据(加权平均和标准偏差)。 如果统计表明正在经历的暂停其时间存在超过目标值的风险时,JVM会修改堆和GC设置以降低它们。 需要注意的是,年轻代和年老代垃圾收集的统计数据是分开计算的,还要注意,默认情况下,最大暂停时间没有被设置。
如果最大暂停时间和最小吞吐量同时设置了目标值,实现最大暂停时间目标具有更高的优先级。 当然,无法保证JVM将一定能达到任一目标,即使它会努力去做。 最后,一切都取决于手头应用程序的行为。
当设置最大暂停时间目标时,我们应注意不要选择太小的值。 正如我们现在所知道的,为了保持低暂停时间,JVM需要增加GC次数,那样可能会严重影响可达到的吞吐量。 这就是为什么对于要求低暂停时间作为主要目标的应用程序(大多数是Web应用程序),我会建议不要使用吞吐量收集器,而是选择CMS收集器。 CMS收集器是本系列下一部分的主题。
强制gc是指java中的垃圾回收站。java中的gc可以自动清理没用的变量占用的内存,从而不需要程序员手动的去释放空间,大大的提高了工作效率和避免了资源。
Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。
Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程 。
Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点 。
Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等 。
1 draw call就是对底层图形程序接口的调用,以便在屏幕上画出东西。调用这些接口的是CPU
2 fragment
3 batching:批处理,将批处理之前需要很多次调用的物体合并,之后只需要调用一次底层图形的接口就可以
1 drawCall影响的是CPU的效率,除了CPU之外,还有一些因素会影响到CPU的效率
2 draw call优化思路
1 GPU的瓶颈主要存在一下的方面
1 保持材质尽可能的少,使得Unity更加便于批处理
2 使用纹理图集,来代替一系列小的贴图。这样可以更快的加载,具有更少的状态转换,批处理更加友好。但是这些不知道babylon支不支持
3 使用光照纹理,而非实时灯光
4 使用LOD
5 使用遮挡剔除
5 压缩,减小显存带宽的压力、使用ETC1格式压缩,使用mipmap
1、GC-MS相对于GC来说价格高,维护成本也很高。一般7890A-5975C联用怎么也要五十多W吧。如果更好的使用MS,最好在进样品之前,先进行GC检测,确定看到合适的峰,峰型,分离都不错,再进行MS定性好一些(当然有一些微量的检测用GC无法检测,可能直接进行MS,那另当别论)。样品非常复杂时,我们一般都关注主要的一种或几种要通过MS定性或定量的物质。也就是说,有时一个样品由几十种物质组成我们不会关注每一种物质的,这样就可以通过一些处理手段了。
2、比如说如果有盐类,或水类不适合直接进样,可以通过顶空的办法,或是通过萃取的办法来进样。可以加入诸如乙酸乙酯这类极性弱一些的溶剂,分层后进行样品检测。这是其中一种办法,还有一种办法是衍生的办法。衍生的方法很多,你可以在网上仔细查找一下。
3、衍生基本就是把含活泼H的羟基,胺基,羧基衍生了,衍生后的产物极性都会变弱,容易萃取和改善峰型,利于GC-MS检测,衍生后也不影响定量的检测。
具体如下:
1、无法自动识别硬盘控制器
使用非正版的个别 *** 作系统光盘,在安装系统时,容易出现此错误。原因是非正版光盘自动加载的硬盘控制器驱动不符合电脑自身需要的驱动。这种情况就建议换正版光盘安装 *** 作系统。
2、手动更新错误的驱动程序
windows *** 作系统正常使用,但手动更新驱动程序把硬盘控制器的驱动程序更新错误,导致此故障。解决方法是进入windows系统高级菜单,选择最后一次的正常配置,即可正常进入系统。
3、bios设置变化后所导致
windows *** 作系统正常,但是由于某些原因,用户修改了bios设置,导致0x0000007b故障。
以上就是关于清gc是什么意思全部的内容,包括:清gc是什么意思、「JVM基础」——垃圾回收基础(GC相关)、gc是什么等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)