Java核心篇之JVM--day3

 Java核心篇之JVM--day3       

 Java JVM详解--通俗易懂教程

 

 

JVM:Java虚拟机的简称。

谈到JVM,通常会聊到三个问题:

1. 什么时候触发Java GC?

2. 对什么东西进行Java GC?

3. 如何进行Java GC?

 

首先解决第一个问题:

1. 什么时候触发Java GC?

GC分为minor GC和Full GC。

Full GC:

  1. 年老代被写满;
  2. 持久代被写满
  3. System.gc被显示调用
  1. 当有新对象生成的时候,如果申请eden空间失败的话,就会触发mino gc,对eden去进行gc处理,清除非存活的对象,并且把尚且存活的对象移到survival区里面。经过一定次数的对象进入老年代的时候,如果老年代的剩余空间放不下升到老年代的对象的时候,就会触发full gc,利用标记清除算法,将不可达的对象清楚,或者小于的时候被handlepromotionFailure参数强制full gc。具体的gc时间是由系统决定的,无法预测。

2. 对什么东西进行GC ?对GC root搜索不到,并且经过第一次标记,清除之后,仍然没有复活的对象进行GC。

3. 做了什么工作,怎么进行GC?

主要做了清理对象,整理内存的工作,Java堆中主要是有新生代和年老代,他们采用不同的回收方式,例如新生代采用了标记复制的算法(因为其生存时间比较短),新生代进行gc的时候,会把eden区存活的对象放到另外一个survival区域里面,然后把eden区和另外一个survival区清除。而年老代采用了标记清除的算法,首先标记出存活的对象,然后移到另一端,这样也能减少内存碎片化。

 

 

 

垃圾收集有哪些算法?

标记清除算法:标记出需要回收的对象,标记完成后,统一回收所有被标记的对象。(两个不足:效率不高:标记和清除都不高;空间问题:产生大量不连续的内存碎片,可能导致以后在分配较大对象的时候因无法找到连续的内存而触发GC)

复制算法:(新生代)比较适合对象存活率比较低的场景。应用于新生代,它主要是把内存分成两个块,每次只使用一块,就像新生代一样,有两个区域:一个是eden区,一个是survival区。这样也就解决了内存碎片化的问题

标记整理算法:(老年代)比较适合对象存活率比较高的场景,应用于老年代,将所有存活对象都移向另一端,然后直接清除掉端边界外的内存。

 

 

如何判断对象是否存活?

引用计数法:每个对象都有一个引用计数器,当对象被引用一次的时候,计数器+1,当对象引用失效的时候,计数值-1,实时性,当对象的引用计数器的值为0,则立刻回收,不能解决循环引用的问题。

可达性算法分析:从GC Root作为起点开始搜索,,那么整个连通图的对象都是存活的对象,对于GC Root无法到达的对象便成了垃圾回收的对象。(解决循环引用的问题)

 

 

常用的引用:

强引用>软引用>弱引用>虚引用

强引用:GC永远都不会回收的对象。内存空间不足时,宁愿抛出OutOfMemoryError。

软引用:内存空间不足时会考虑回收它,空间足够的时候不会

弱引用:不管内存空间够不够,都会回收它

虚引用:不会影响生存时间,目的是能在这个对象被收集器回收时收到一个系统通知

 

  1. 哪些对象可以作为GC Root对象

虚拟机栈中的对象

方法区的静态变量

方法区常量池的对象

 

 

  1. JVM垃圾收集器:

 

 

 

分为新生代收集器,老年代收集器:

新生代收集器:

在执行机制上JVM主要提供了串行GC(serial GC),并行GC(ParNew),并行回收GC(parallel scavenge)

Serial GC:在整个GC的过程中采用单线程的方式来进行垃圾回收,在回收过程中,必须停止其他所有的工作线程。 适用于单CPU,是client模式下默认的GC方式。

parNew :其实就是serialGC的多线程版本,除了使用多条线程来进行垃圾收集之外,其他行为跟serialGC差不多。,是server模式下默认使用的GC方式。能够与CMS收集器配合工作。

Parallel scavenge:它跟parNew差不多,也是一个并行的多线程收集器。不过他的关注点跟其他收集器不一样。Cms等收集器的关注点是尽可能的缩短垃圾收集是用户线程的停顿时间,而parallel scavenge的目的是为了达到一个可控制的吞吐量。(也就是CPU用于运行用户代码的时间与CPU总的消耗时间的比值)还有一个就是parallel scavenge有GC的自适应调节策略:我们可以通过一个参数,这个参数叫做userAdaptiveSizePolicy来让虚拟机帮我们动态的调整这些参数以提供最合适的停顿时间或者最大的吞吐量。

 

 

老年代收集器:

 

串行GC(serial old):他是serial的老年代版本,也是一个单线程收集器,使用标记整理算法。

并行GC(parallel old):是parallel scavenge 的老年代版本。使用多线程和“标记-整理”算法。

 

 

并发GC(CMS):获取最短回收停顿时间为目标的收集器。

优点是:并发收集,低停顿

总结如下:

  1. 初始标记:标记一下GC root能够直接关联到的对象,速度很快
  2. 并发标记:进行GC root tracing的过程,耗时比较长,并发,
  3. 重新标记:为了修正并发标记期间因为用户程序继续运行而导致标记产生变动的那一部分对象的的标记记录。
  4. 并发清除:耗时较长,并发。
  5. 这四个过程中,耗时最长的并发标记和并发清除过程收集器线程都可以与用户线程一起工作,所以,整体上说:cms收集器的回收过程时与用户线程一起工作的。

缺点有三:

  1. 对cpu资源敏感,因为并发标记和并发清除过程中会占用cpu,公式是:

(cpu数量+3)/4,当cpu<4的时候,占用了不少于25%的cpu资源。(增量式并发收集器:让他们交替执行)

  1. 无法处理浮动垃圾:在第四个阶段并发清理的时候,因为用户线程还在运行,所以就会有新的垃圾产生,这些就是浮动垃圾,cms是无法在当次收集中处理掉他们的。(运行期间要预留内存给他们,不然会出现concurrent mode failure)
  2. 因为他是基于标记-清除算法进行清除的,所以将会产生内存碎片化的问题,这将给大对象分配带来麻烦。

 

成熟的收集器:

G1:G1收集器是当今收集器技术发展最前沿的成果,他是一款面向服务端应用的收集器。

过程如下:

  • 初始标记:标记一下GC root能直接关联到的对象。,需要停顿线程,耗时短。
  • 并发标记:从gc root开始对堆中的对象进行分析,找出存活的对象,耗时长,但是可以和用户线程并发执行。
  • 最终标记:为了修正在并发标记过程中因用户程序继续运作而导致标记产生变动的那一部分标记记录。这个阶段需要停顿用户线程。
  • 筛选回收:首先对各个region的回收价值和成本进行排序,根据用户所期望的停顿时间来指定回收计划。

优势:

  1. 并行与并发:G1能够充分利用CPU,多核环境下硬件的优势,使用多个CPU来缩短stop-the-world停顿时间。
  2. 分代收集:与其他收集器一样,分代概念在G1仍然保存。
  3. 空间整合:与cms的“标记-清除算法”不同,G1整体上看来是基于“标记-整理的算法”来实现的收集器,这意味着在G1运行期间不会产生内存空间碎片。。
  4. 可预测停顿:这是G1相对于CMS的一大优势,降低低停顿时间是cms和G1共同的关注点,但是G1还能建立可预测的停顿时间模型,让使用者明确指定在一个时间为M的时间片段内,消耗在垃圾收集的时间不得超过N毫秒。

 

垃圾收集器参数总结:

 

 

userSerialGC:虚拟机运行在client模式下的默认值,打开此开关之后,使用serial+serial old组合收集器。

userParNewGC:打开此开关之后,使用parNew+serial Old组合收集器。

userConcMarkSweepGC:打开此开关之后,使用parNew+CMS+serial Old组合垃圾收集器,serial old作为后备收集器使用。(concurrent mode failure)

userParallelGC:server模式下的默认值,parallel Scavenge+serial old组合垃圾收集

userParallelOldGC:parallel scavenge+parallel old收集器组合收集。

SurvivalRadio:eden:survival= 8

userAdaptiveSizePolicy:GC自适应调节策略,调整Java堆各区域的大小以及进入老年代的年龄。

handlePromotionFailure:是否允许分配担保失败

ParallelGCThreads:设置并行GC时进行内存回收的线程数。

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/558932.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用springboot来实现WebLog

使用websocket技术实时输出系统日志到浏览器端&#xff0c;实现WebLog boot-websocket-log&#xff1a; spring boot系统中使用websocket技术实时输出系统日志到浏览器端&#xff0c;因为是实时输出&#xff0c;所有第一时间就想到了使用webSocket,而且在spring boot中&#…

设计模式---观察者模式介绍与理解

设计模式---观察者模式介绍与理解&#xff1a; 观察者模式原理&#xff1a;类似于定牛奶业务 1. 奶站&#xff0c;subject&#xff1a;登记注册&#xff0c;移除&#xff0c;通知&#xff08;register&#xff0c;remove&#xff0c;notify&#xff09; 2. 用户&#xff0c;…

CRS-4995: The command ‘start resource’ is invalid in crsctl.

ntp时间调整后&#xff0c;节点1&#xff0c;advm 和acfs offline 处理办法&#xff1a; /u01/app/12.2.0.1/grid/bin/crsctl stop crs /u01/app/12.2.0.1/grid/bin/crsctl start crs 曾经尝试如下命令不起作用 /u01/app/12.2.0.1/grid/bin/acfsload start /u01/app/12.2…

抽象工厂模式升级版————泛型化实现

引言 今天回看之前总结的抽象工厂模式的实现《Java常用设计模式————抽象工厂模式》&#xff0c;聚焦于抽象工厂模式的缺点&#xff0c;试着改进了一下。 回顾一下抽象工厂模式的缺点&#xff1a; 在添加新的产品类型时&#xff0c;难以扩展抽象工厂来生产新种类的产品。…

发生在“注解”@的那些事儿

注解&#xff1a; 自定义注解&#xff1a; 注解和类&#xff0c;接口一样&#xff0c;属于一种数据类型 注解可以放在类&#xff0c;方法&#xff0c;属性上面 注解可以有属性&#xff0c;也可以没有属性 注解有作用范围 &#xff08; 源码期间&#xff08;String&#…

Java常用设计模式————建造者模式

引言 建造者模式&#xff08;Builder Pattern&#xff09;使用多个简单对象一步一步构建成一个复杂的对象。这种类型的设计模式属于建造型模式&#xff0c;它提供了一种创建对象的最佳方式。 一个Builder会一步步构建最终的对象。该Builder类是独立于其他对象的。 实现概要 …

使用动态代理解决网站字符集编码问题:(之前通过拦截器)

使用动态代理解决网站字符集编码问题&#xff1a;&#xff08;之前通过拦截器&#xff09; 设计模式&#xff1a; 在软件开发的过程中&#xff0c;遇到相识的问题&#xff0c;将问题的解决方式抽象为模型&#xff08;套路&#xff09; 单例模式&#xff08;静态代码只会执行一…

设计模式---简单工厂设计模式

先定义一个抽象类Animal&#xff1a; 定义两个动物类继承这个类&#xff1a; 定义一个专门生产动物的工程类&#xff1a; 最后定义一个测试类&#xff1a; 按照这个动物工厂类&#xff0c;你会发现&#xff0c;如果动物一多的话&#xff0c;就需要写很多重复的方法&#xff0c;…

Java 多线程 —— ThreadLocal

一、引言 ThreadLocal是Java帮助实现线程封闭性的典型手段。 作用&#xff1a;提供线程内的局部变量&#xff0c;这种变量在线程的生命周期内起作用&#xff0c;减少同一个线程内多个函数或组件之间一些公共变量的传递复杂度。同时也用来维护线程中的变量不被其他线程干扰。 …

设计模式---适配器设计模式

设计模式---适配器设计模式 什么事适配器&#xff1a; 1. 在使用监听的时候&#xff0c;需要定义一个类事件监听器接口 2. 通常接口中有多个方法&#xff0c;而程序中不一定所有的方法都用到&#xff0c;但又必须重写&#xff0c;很繁琐 3. 适配器简化了这些操作&#xff0c…

Java并发编程实战————售票问题

引言 现有一个需求如下&#xff1a; 有10000张火车票&#xff0c;每张票都有一个编号&#xff0c;同时有10个窗口对外售票&#xff0c;如何确保车票的正常售卖&#xff1f; 程序一&#xff1a;使用List 问题的解决办法都是从我们最最熟悉的角度思考。程序一&#xff0c;我们…

多线程相关知识

多线程相关知识 两个线程进行通信&#xff1a;通过等待&#xff08;wait&#xff09;唤醒&#xff08;notify&#xff09;机制 三个或三个以上线程进行通信&#xff1a;通过notifyAll&#xff08;&#xff09;方法 /* * 1. 在同步代码块中&#xff0c;用哪个对象锁&#xff0c…

Eclipse集成PyDev5.2.0开发插件

引言 在进行Python学习的时候&#xff0c;希望不使用IDLE进行开发&#xff0c;但是其他的IDE如PyCharm可能需要一段短暂时间的上手&#xff0c;因为开发过Java&#xff0c;所以使用能够集成到Eclipse上的PyDev插件进行开发应该会好一些。 但是在安装PyDev的时候发生了一些问题…

PostMan 四种常见的 POST 提交数据方式

HTTP/1.1 协议规定的 HTTP 请求方法有 OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT 这几种。其中 POST 一般用来向服务端提交数据&#xff0c;本文主要讨论 POST 提交数据的几种方式。 协议规定 POST 提交的数据必须放在消息主体&#xff08;entity-body&#xff0…

史上最真实行业鄙视链

本文转载自菜鸟教程的微信公众号&#xff0c;原文链接&#xff1a;https://mp.weixin.qq.com/s/d9cdtq8y4Msq-_ZNof-iuw 引言 作为程序员的一份子&#xff0c;掌握好各个生态系统中的鄙视链&#xff0c;可以写出更加符合改变世界要求的代码。掌握了鄙视链&#xff0c;就掌握了…

权限验证框架Shiro

权限验证框架Shiro&#xff1a; Shiro简介 什么是Shiro&#xff1a; shiro是一个强大易用的Java安全框架&#xff0c;提供了认证&#xff0c;授权&#xff0c;加密&#xff0c;回话管理等功能&#xff1b; 认证&#xff08;Authentication&#xff09;&#xff1a;用户身份识别…

Mybatis从入门到精通上篇

Mybatis从入门到精通上篇&#xff1a; 学习过的持久层框架&#xff1a;DBUtils , Hibernate Mybatis就是类似于hibernate的orm持久层框架。 Mybatis介绍&#xff1a; Mybatis是面向sql的持久层框架&#xff0c;他封装了jdbc访问数据库的过程&#xff0c;我们开发&#xff0c;只…

Eclipse使用————Working Set工作集

引言 经常看到在设置项目的时候&#xff0c;如导入项目&#xff0c;新建项目等看到对话框的下方有一个“add to working set”复选框&#xff0c;为了弄清这个working set&#xff0c;我们就来好好了解一下Eclipse 的working set功能。 Working Set&#xff1f; Eclipse中通…

Mybatis从入门到精通下篇

Mybatis从入门到精通下篇&#xff1a; 输入类型&#xff1a; 输出类型&#xff1a; ResultMap&#xff1a; 动态sql&#xff1a; if标签&#xff1a; where标签&#xff1a; sql片段&#xff1a; foreach标签&#xff1a; 关联查询&#xff1a; 以订单作为主体&#xff1a; 一…

爱上进制转换练习

引言 对于可能接触到通讯行业或是物联网的开发工作者&#xff0c;一般会面对十进制、二进制、十六进制的转换工作&#xff0c;不仅仅是体现在代码上&#xff0c;有时候也需要用肉眼来进行快速的转化&#xff0c;以获取协议指令中的信息。 今天通过简单的整理&#xff0c;特此…