轻gc和重gc分别在什么时候发生_GC发展与现状

GC发展

Java不像C或C++那样,需要程序员在编程的过程中,时刻注意申请内存保存对象,在对象使用完成后,要在合适的时机将对象占用的内存释放掉(析构函数);Java得意与内部的三大机制,保证了程序开发方便:

  • 解释执行+ 即时编译器JIT,对热点代码的即时编译执行为机器,在方法区中保存代码缓存;

  • 执行引擎;

  • 垃圾回收机制;

我们今天的重点就是要阐述:垃圾回收机制。

为什么要进行垃圾回收?

原因很简单:现在的计算机系统都是跑在程序存储结果的计算机上的,程序必须首先通过IO加载到内存中,才能开始创建程序进程,开始运行。而内存的大小是有上限的,无休止地在内存中创建对象,占用内存,而不去清理,必然是会造成内存不足,导致操作系统将应用进程杀死。

所以就需要java字节码,要么字节码中管理内存,申请内存,扩展内存,释放内存;要么JVM自己提供垃圾回收机制;


要进行垃圾回收,首先就要知道,对象保存在哪里?什么样的对象是垃圾?

对象保存在哪里?

对象在中保存,小的对象可能会保存在栈的TLAB中,JVM的内存区域分五个部分,其实在实际中,java所使用的内存包括有(后续补充)??

java内存 =  PC寄存器 + java栈 + 本地栈 + 年轻代 +老年代 + 直接内存空间

堆的逻辑划分

1d14266ef524234abb5a553421fb402b.png

分别介绍如下:

程序计数器PC:是一块较小的内存空间,作用可以看做是当前线程所执行的字节码的行号的指示器,线程私有。

JVM方法栈和本地方法栈:在sun的jdk中,JVM方法栈和本地方法栈是算在一起的,虚拟机栈为虚拟机执行java方法,本地方法栈为虚拟机执行Native方法,线程私有。

java heap:是虚拟机中内存区域最大的一块,细分可以分为新生代和旧生带,新生代可以划分为E、S0、S1,其中S1和S0又可以叫做from 或 to,线程共享。

方法区:存放了要加载的类的信息,类中的静态变量,定义为final的常量,类中的Field信息,方法信息等,全局共享,又叫做持久带,可以通过  -XX:PermSize和-XX:MaxPermSize设置最小值和最大值,线程共享。

各个区的作用

图示:

134cda826d2f77fa60a7e83d6e32221a.png

新生代:

   大多数情况下,java中新建的对象都是在新生代上分配的,新生代由Eden和两块相同大小的S0和S1组成,其中S0和S1又称为From和To(这个划分没有先后顺序),可以通过-Xmn来设置新生代的大小,-XX:SurvivorRatio设置Eden和S区的比值,有些垃圾回收器会对S0或者S1进行动态的调整。

    之所以说大多数情况下新建的对象在新生代上分配,是因为有两种情况下java新创建的对象会直接到旧生带,一种是大的数组对象,且对象中无外部引用的对象,另外一种是通过

启动参数上面进行设置-XX:PretenureSizeThreshold=1024(单位是字节),意思是对象超过此大小,就直接分配到老年代的堆内存中,此外,并行垃圾回收器可以在运行期决定那些对象可以直接创建在旧生带。

老年代:

多次回收之后仍然存活的对象,大小是-Xms减去-Xmn。

常见的参数设置

-XX:+ 启用选项

-XX:- 不启用选项

-XX:= 给选项设置一个数字类型值,可跟单位,例如 32k, 1024m, 2g

-XX:= 给选项设置一个字符串值,例如-XX:HeapDumpPath=./dump.core

什么是垃圾对象

Java采用的是可达性分析法。

判断对象是否为垃圾的方法有两种:

  • 引用计数法

  • 可达性分析算法

可达性分析算法中,有个非非常常的概念:根集合,引用链:

根集合

(1)根集合,包含了一组对象,这些是对运行时数据区的对象快照的扫描,主要包含有:

  • java虚拟机栈(栈帧中的本地变量表)中的引用的对象

  • 本地方法栈中JNI本地方法的引用对象。

  • 方法区中的类静态属性引用的对象

  • 方法区中的常量引用的对象。

  • 常驻的异常对象,锁对象

  • 其他代的堆内存中,对当前回收内存区域有引用关系的对象;比如:young gc时,出现的老年代中的对象,G1回收时Region中的remember set对象

引用链

从根集合出发,开始遍历堆内存中的对象,在引用链上的对象,就是正在使用的对象,不是垃圾;没有在引用链上的对象,就是垃圾,垃圾回收器就要对其进行回收处理。

STW的时机

为了确保堆内存中的对象间的引用关系是不变的,在进行确定根集合时,需要将应用程序暂时停顿,这也是后续垃圾回收器在努力奋斗进行攻克的一个重要参数,停顿时间,越小越好,吞吐量越大越好。

STW的时机:

安全点

哪些时刻作为安全点:

  • 方法开始执行;

  • 方法返回之前;

  • 异常抛出

  • 进入循环调用前

安全区域

哪些时间区域作为安全区域:

  • sleep()操作

  • 线程阻塞时


垃圾回收算法

三种垃圾回收算法和java最后选择的回收算法

复制算法

所有的年轻代的收集算法

标记-清除算法

CMS的垃圾回收算法

标记-整理算法

Parallel old的收集算法

Java选择的垃圾回收算法:分代回收算法,将堆内存进行逻辑划分为:根据对象的年龄大小,划分为年轻代,年老代保存,在不同的代,使用不同的回收算法。


垃圾回收器

第一阶段 串性回收

用在客户端模式的java虚拟机上,

暂停应用线程,单线程地回收垃圾对象;

第二阶段 并行回收

暂停应用线程,启动多个GC线程地回收垃圾对象;

对比串性回收的速度高了,停顿的时间变短了,但是仍是在整个回收过程中,只有GC运行,应用线程是不工作的;

第三阶段 并发回收

在GC的过程中,根据GC过程的不同阶段,将部分阶段设置为GC线程和应用线程同时运行,并且最大限度地减少GC造成的暂停时间,这个过程包括有:

  • 收集根对象;

  • 初始标记

  • 并发标记

  • 最终标记

  • 并发清除

举例:CMS垃圾回收器

第四阶段 标记和回收分离

标记和回收都是并发的,并且标记有标记的触发条件;

回收有回收的触发条件,两个条件相互影响。

举例:G1,ZGC

CMS三个很重要的参数

  • -XX:CMSInitiatingOccupancyFraction

设置CMS收集器在老年代空间被使用多少(百分比)后触发垃圾收集。默认设置-XX:CMSInitiatingOccupancyFraction=68表示老年代空间使用比例达到68%时触发CMS垃圾收集。仅当老年代收集器设置为CMS时候这个参数才有效。

  • -XX:+UseCMSCompactAtFullCollection

设置CMS收集器在完成垃圾收集后是否要进行一次内存碎片整理。仅当老年代收集器设置为CMS时候这个参数才有效。

  • -XX:CMSFullGCsBeforeCompaction

设置CMS收集器在进行多少次垃圾收集后再进行一次内存碎片整理。如设置-XX:CMSFullGCsBeforeCompaction=2表示CMS收集器进行了2次垃圾收集之后,进行一次内存碎片整理。仅当老年代收集器设置为CMS时候这个参数才有效。

  • 日志有关的三个参数:
    - -XX:+PrintGCDateStamps

-XX:+PrintGCDetails

-Xloggc

指定gc日志的存放位置。如-Xloggc:/var/log/myapp-gc.log表示将gc日志保存在磁盘/var/log/目录,文件名为myapp-gc.log

到底Java GC是在什么时候,对什么东西,做了什么事情?

(1)时间:

JVM进程启动后,就会不断地在新生代中保存新创建的对象,当Eden区满了后触发minor gc,用的是复制算法,当Survivor中的一半以上的对象存活年龄大于平均年龄时,或者对象的年龄大于设置的参数:-XX:MaxTenuringThreshold时,就会触发对象晋升,从年轻代晋升到老年代保存,当晋升到老年代的对象大小总和大于老年代剩余空间full gc时,并且晋升担保机制设置为ture时,就会直接尝试晋升,老年代内存不足时,触发老年代full gc,或者小于时被HandlePromotionFailure参数强制full gc,gc与非gc的耗时比较后,超过了GCTimeRatio的限制引发OOM:

  • 通过参数NewRatio控制年轻代和老年代的堆空间的比例;

  • 通过参数SurvivorRatio控制年轻代中,伊甸园区和幸存者区的比例

  • 通过参数:-XX:MaxTenuringThreshold设置从年轻代晋升到老年代的对象年龄,其中:CMS是默认:15,G1默认是:6;

GC关键技术

三色标记法

白色:还没标记,或者标记为了垃圾对象;

灰色:标记一半,属性没有标记完成

黑色:自己和自己的属性都已近全部标记完成。

记忆集

用来保存其他堆内存区,对当前GC线程作用的堆内存区的引用关系;

卡表

用来记录对其他代,或其他Region中的对象,有当前card的引用指向时,就将当前card标记为dirty,并且在垃圾回收时,将dirty保存到drity card queue中;

目的:在进行垃圾回收时,防止对全堆进行扫描,从而降低并发标记或最终标记的暂停时间;

全称是Remembered Set,是辅助GC过程的一种结构,典型的空间换时间工具,和Card Table有些类似。还有一种数据结构也是辅助GC的:Collection Set(CSet),它记录了GC要收集的Region集合,集合里的Region可以是任意年代的。在GC的时候,对于old->young和old->old的跨代对象引用,只要扫描对应的CSet中的RSet即可。

逻辑上说每个Region都有一个RSet,RSet记录了其他Region中的对象引用本Region中对象的关系,属于points-into结构(谁引用了我的对象)。而Card Table则是一种points-out(我引用了谁的对象)的结构,每个Card 覆盖一定范围的Heap(一般为512Bytes)。G1的RSet是在Card Table的基础上实现的:每个Region会记录下别的Region有指向自己的指针,并标记这些指针分别在哪些Card的范围内。这个RSet其实是一个Hash Table,Key是别的Region的起始地址,Value是一个集合,里面的元素是Card Table的Index。

a77bd660bdc1d7563685943a9e58417d.png

下图表示了RSet、Card和Region的关系:

821af19b7b0db45084eb3bd5aafb0a1b.png

SATB

当G1开始进行回收时,为了确保堆内存中,对象之间的引用关系不变,而获取一个内存快照,进行并发标记的作用对象就是这个SATB内存快照;

CMS和G1算法都涉及对可达对象的并发标记。并发标记的主要问题是collector在标记对象的过程中mutator可能正在改变对象引用关系图,从而造成漏标和错标。错标不会影响程序的正确性,只是造成所谓的浮动垃圾。但漏标则会导致可达对象被当做垃圾收集掉,从而影响程序的正确性。

为解决漏标问题,GC Handbook一书首先将对象分为三类,即所谓的black对象,grey对象和white对象。white对象是那些还没有被collector标记到的对象;grey对象是那些自身已经被标记到,但其所有引用字段还没有处理的对象;而black对象则是自身已经被标记到,且其引用的所有对象也已经被标记的对象。

基于上述分类,一个white对象在并发标记阶段会被漏标的充分必要条件是:

1、mutator插入了一个从black对象到该white对象的新引用

2、mutator删除了所有从grey对象到该white对象的直接或者间接引用。

因此,要避免对象的漏标,只需要打破上述2个条件中的任何一个即可。

CMS:

Incremental update关注的是第一个条件的打破,即引用关系的插入。Incremental update利用write barrier将所有新插入的引用关系都记录下来,最后以这些引用关系的src为根STW地重新扫描一遍即避免了漏标问题。

G1:

SATB关注的是第二个条件的打破,即引用关系的删除。SATB利用pre write barrier将所有即将被删除的引用关系的旧引用记录下来,最后以这些旧引用为根STW地重新扫描一遍即可避免漏标问题。

在G1中,使用的是STAB(snapshot-at-the-beginning)的方式,删除的时候记录所有的对象,它有3个步骤:

1,在开始标记的时候生成一个快照图标记存活对象

2,在并发标记的时候所有被改变的对象入队(在write barrier里把所有旧的引用所指向的对象都变成非白的)

3,可能存在游离的垃圾,将在下次被收集

614ae70c745ecc89fc41d198f4a2fb85.png95a3f096f47f0163e2bd55e2f14ed664.pngf5082fab4dd235086787ced5b6978760.png

G1的写前屏障

G1在并发标记过程中,当对象与对象之间的引用关系发生变化时,就会将引用断开的对象,保存起来,在并发阶段的后期,重新对这些对象进行扫描标记;

目的:防止对象消失,

CMS的增量更新

CMS在进行并发标记过程中,当对象间的引用关系发生变化时,就会引用发生变化的对象,利用增量更新的条件,使用写后屏障技术保存起来,在最终标记阶段,将会把根集合和并发标记阶段引用发生变化的对象为新的根集合,重新扫描一遍所有的对象;

目的:防止对象消失;

缺点:可能存在浮动垃圾;

染色指针

多个虚拟内存地址,根据地址中特殊位置的标记位,用来表示哪个地址段是有效的,从而实现多个虚拟内存地址,对应一个物理内存地址,可支持最大内存空间为:

16T;

G1的标记过程

概述

STAB全称Snapshot-At-The-Beginning,由字面理解,是GC开始时活着的对象的一个快照。它是通过Root Tracing得到的,作用是维持并发GC的正确性。那么它是怎么维持并发GC的正确性的呢?根据三色标记算法,我们知道对象存在三种状态:

  • 白:对象没有被标记到,标记阶段结束后,会被当做垃圾回收掉,即灰色节点的子节点。

  • 灰:对象被标记了,但是它的field还没有被标记或标记完。

  • 黑:对象被标记了,且它的所有field也被标记完了。

由于并发阶段的存在,那就有可能在并行运行期间之前的标记过的对象的引用关系可能被改变,就会出现白对象漏标的情况,这种情况发生的前提是:

  • 把一个白对象的引用存到黑对象的字段里,如果这个情况发生,因为标记为黑色的对象认为是扫描完成的,不会再对它进行扫描。

  • 某个白对象失去了所有能从灰对象到达它的引用路径。

对于第一个条件,在并发标记阶段,如果该白对象是new出来的,并没有被灰对象持有,那么它会不会被漏标呢?

如果灰对象到白对象的直接引用或者间接引用被替换了,或者删除了,白对象就会被漏标,从而导致被回收掉,这是非常严重的错误。

解决新创建对象产生的漏标问题

        SATB算法机制中,会在GC开始时先创建一个对象快照,在并发标记时所有快照中当时的存活对象就认为是存活的,标记过程中新分配的对象也会被标记为存活对象,不会被回收。这种机制能够很好解决新创建对象漏标的情况。STAB核心的两个结构就是两个Bitmap。

       Bitmap分别存储在每个Region中,并发标记过程里的两个重要的变量:preTAMS(pre-top-at-mark-start,代表着Region上一次完成标记的位置) 以及nextTAMS(next-top-at-mark-start,随着标记的进行会不断移动,一开始在top位置)。SATB通过控制两个变量的移动来进行标记,移动规则如下:

  • 假设第n轮并发标记开始,将该Region当前的Top指针赋值给nextTAMS,在并发标记标记期间,分配的对象都在[ nextTAMS, Top ]之间,SATB能够确保这部分的对象都会被标记,默认都是存活的。

  • 当并发标记结束时,将nextTAMS所在的地址赋值给previousTAMS,SATB给[ Bottom, previousTAMS ]之间的对象创建一个快照Bitmap,所有垃圾对象能通过快照被识别出来。

  • 第n+1轮并发标记开始,过程和第n轮一样。

d4ffaa575c3206f04ee86711fc82eb01.pngf2598aec7eb4efb12278ebdc17fcb044.png

  • A阶段,初始标记阶段,需要STW,将扫描Region的Top值赋值给nextTAMS。

  • A-B阶段:并发标记阶段。

  • B阶段,并发标记结束阶段,此时并发标记阶段生成的新对象都会被分配在[nextTAMS,Top]之间,这些对象会被定义为“隐式对象”,同时_next_mark_bitmap也开始存储nextTAMS标记的对象的地址。

  • C阶段,清除阶段,_next_mark_bitmap_prev_mark_bitmap会进行交换,同时清理[ Bottom, previousTAMS ]之间被标记的所有对象,对于“隐式对象”会在下次垃圾收集过程进行回收(如第F步),这也是SATB存在弊端,会一定程度产生未能在本次标记中识别的浮动垃圾。

解决对象引用被修改产生的漏标问题

        SATB利用pre-write barrier,将所有即将被修改引用关系的白对象旧引用记录下来,最后以这些旧引用为根重新扫描一遍,以解决白对象引用被修改产生的漏标问题。

在引用修改时把原引用保存到satb_mark_queue中,每个线程都自带一个satb_mark_queue。在下一次的并发标记阶段,会依次处理satb_mark_queue中的对象,确保这部分对象在本轮GC中是存活的。

        如果被修改引用的白对象就是要被收集的垃圾,这次的标记会让它躲过GC,这就是float garbage。因为SATB的做法精度比较低,所以造成的float garbage也会比较多。

总结

  1.  本文主要对GC发展做了详述,分布式高并发的环境,造就了GC不断发展,要在最短的时间内,给用户响应最多的返回数据,就需要后端服务有很强的响应能力;

  2. 就需要GC的暂停时间段,GC回收的效率越高越好。

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

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

相关文章

nginx离线安装_web高可用-基于keepalived和nginx

一.体系架构在Keepalived Nginx高可用负载均衡架构中,keepalived负责实现High-availability (HA) 功能控制前端机VIP(虚拟网络地址),当有设备发生故障时,热备服务器可以瞬间将VIP自动切换过来,实际运行中体验只有2秒钟…

php mysql 实现原理_php+mysql分页原理实现

完整代码如下:!htmlhead-"-type"";GBK"styletype"text/css"body{font-size:12px;font-family:verdana;width:100%;}div.page{text-align:center;}div.content{height:300px;}div.pagea{border:#aaaadd1pxsolid;text-decoration:none;…

python任意代码都可以缩进去_我发现了个 Python 黑魔法,执行任意代码都会自动念上一段 『平安经』...

最近的"平安经"可谓是引起了不小的风波啊。作为一个正儿八经的程序员,最害怕的就是自己的代码上线出现各种各样的 BUG。为此,明哥今天分享一个 Python 的黑魔法,教你如何在你执行任意 Python 代码前,让 Python 解释器自…

域用户更改密码提示拒绝访问_AD域中的ACL攻防探索

前言关于域内ACL的攻防近两年经常被人所提起,同时也产生了很多关于域内ACL相关的工具和攻击方式,本文将会从ACL的概念谈起,然后介绍几种不同的域内攻击方式以及如何监测和防御对于ACL的攻击。ACL的概念和作用ACM:首先想要了解ACL首…

go MySQL 多语句_八、MySQL经典查询语句-Go语言中文社区

student表course表score表teacher表1、 查询Student表中的所有记录的Sname、Ssex和Class列。select Sname,Ssex,Class from Student;2、 查询教师所有的单位即不重复的Depart列。select distinct Depart from Teacher3、 查询Student表的所有记录。select * from Student4、 查…

如何干净的删除vm_如何在macOS 10.15 Catalina绕过XProtect?

在macOS 10.15 Catalina中,Apple进行了许多安全性能地改进,包括通过使所有可执行文件都受XProtect扫描来加固系统,而不管文件是否带有com.apple.quarantine位标记。对于安全研究人员而言,这意味着不再像以前的macOS一样&#xff0…

activexobject对象不能创建_Oracle数据库用户管理之系统权限和对象权限

【关键术语】Privileges 权限System privileges 系统权限Object privileges 对象权限Grant 授予Revoke 撤消2.1 Oracle 权限概述2.1.1 权限的作用权限(privilege)是指执行特定类型 SQL 命令或访问其他模式对象的权利。Oracle 使用 权限来控制用户对数据的访问以及用户所能执行的…

【啃不完的算法导论】- 动态规划 - 最长公共子序列(概念篇)

以下内容纯是为了熟悉《算法导论》中的内容,高手可略过,其中涉及的书本内容的版权归原作者、译者、出版社所有 求最长公共子序列,一个典型的 动态规划题 和 字符串处理算法,写在这里是希望自己以后能多来看看和改改,温…

python发送邮箱_你知道怎么用Python发送邮件吗?

作者 | 陈熹来源 | 早起Python(ID:zaoqi-python)头图 | CSDN 下载自东方IC前言本文主要对邮件操作基础知识及代码进行介绍,用Python发邮件有哪些优势?批量发送邮件,并且各邮件可以不同高度自定义的定时发送更有效地管理收件箱基本…

centos中安装mysql5.6_CentOS中安装MySQL5.6报错的解决方法

由于项目需要,必须使用最新出来的MySQL5.6社区版本,使用的操作系统是CentOS6.3。然后安装到中途报错如下:file /usr/share/mys由于项目需要,必须使用最新出来的MySQL5.6社区版本,使用的操作系统是CentOS6.3。首先&…

使用Wireshark进行SIP包解析

1. 安装Wireshark 下载Wireshark后,安装很简单,基本上只需要点击“Next”和“I agree”等按钮,不再赘述。 2. Wireshark介绍 参见:http://man.lupaworld.com/content/network/wireshark/Introduction.html copy一下简要介绍&a…

Android-Animations的使用大全之二:Frame Animation和其他

Android-Animations的使用大全之一&#xff1a;Tweened Animations详解 5 Frame-By-Frame Animations的使用方 1 在res/drawable中创建一个xml文件&#xff0c;定义Animation的动画播放序列 anim_nv.xml Xml代码 <animation-list xmlns:android"http://schemas.androi…

wireshark分析SIP协议——注册

SIP 是VOIP目前非常流行的一种协议。有关协议的详细原理参照相关文档。本文通过wireshark抓包分析SIP user agent&#xff08;用户代理客户机&#xff0c;uac&#xff09;与SIPserve之间的交互过程&#xff0c;在拨打SIP电话之前&#xff0c;先需要搭建相应的环境&#xff1a;根…

micropython仿真器_Micropython教程之TPYBoard DIY超声波测距仪实例演示

1.实验目的 1. 学习在PC机系统中扩展简单I/O?接口的方法。 2. 进一步学习编制数据输出程序的设计方法。 3. 学习超声波模块的测距原理。 4. 学习LCD5110接线方法 5. 学习TPYboard控制超声波模块测距。(萝卜学科编程教育tpyboard。com) 2.所需元器件 超声波模块一个 TPYBoard板…

monotouch在ipad中的实例应用--显示图像和文字

本节主要讲述在苹果环境中使用monodevelop开发ipad的一个实例&#xff0c;具体操作如下 1、新建项目 选择monotouch--ipad--Empty project 命名为iPad01 2、添加新文件&#xff0c;选择monotouch--ipad view&#xff0c;命名为showView&#xff0c;这样会在项目中多出来三个文件…

MTU MSS 详解记录

先学习理解一下帧的封装格式&#xff1a; 需要注意的是&#xff0c;区别两种帧封装格式&#xff1a;802标准帧和以太网帧1&#xff0c;在802标准定义的帧格式中&#xff0c;长度字段是指它后续数据的字节长度&#xff0c;但不包括C R C检验码。RFC 1042&#xff08;IEEE 802&a…

通达oa 不允许从该ip登陆_通达OA-命令执行漏洞复现

通达OA-命令执行一、环境安装文件&#xff1a;链接:https://pan.baidu.com/s/1Y78Zs-7Igi4MRE0J_Dp-dQ 提取码:2b3i二、漏洞验证任意文件上传漏洞 /ispirit/im/upload.php本地文件包含漏洞 /ispirit/interface/gateway.php这两个路径不需要登录认证。burp抓包修改数据包上传文件…

mysql数据转存到时序数据库_干货丨如何高速迁移MySQL数据到时序数据库DolphinDB...

DolphinDB提供了两种导入MySQL数据的方法&#xff1a;ODBC插件和MySQL插件。我们推荐使用MySQL插件导入MySQL数据&#xff0c;因为它的速度比ODBC导入更快&#xff0c;导入6.5G数据&#xff0c;MySQL插件的速度是ODBC插件的4倍&#xff0c;并且使用MySQL插件无需任何配置&#…

优秀程序员的45个习惯

摘要&#xff1a;值得打印出来贴在办公室墙上学习实践的箴言。 优秀来自好的习惯。怎样成为优秀的开发人员&#xff1f;图灵公司最近热销的《高效程序员的45个习惯》一书给出了很好的解答&#xff0c;非常值得一读。 这本书的英文原版荣获了有软件奥斯卡之称的Jolt生产效率大奖…

java 类型转换_java中的基本数据类型的转换

本文参考了如下两篇文章:Java中&#xff0c;经常可以遇到类型转换的场景&#xff0c;从变量的定义到复制、数值变量的计算到方法的参数传递、基类与派生类间的造型等&#xff0c;随处可见类型转换的身影。Java中的类型转换在Java编码中具有重要的作用。首先&#xff0c;来了解下…