内存整理英菲兰朵是哪里出产品的产品啊?怎么自己矛盾啊?开始说了不用root,如图是我打开了以后的截图,

有关JVM 内存管理你知道多少_武汉Java培训
有关JVM 内存管理你知道多少
时间: 10:30
发布:武汉Java培训机构
来源:互联网
1)JVM 内存划分:
方法区(线程共享):常量、静态变量、JIT(即时编译器) 编译后的代码也都在方法区;
堆内存(线程共享):垃圾回收的主要场所;
程序计数器: 当前线程执行的字节码的位置指示器;
虚拟机栈(栈内存):保存局部变量、基本数据类型变量以及堆内存中某个对象的引用变量;
本地方法栈 :为 JVM 提供使用 native 方法的服务。
2)类似-Xms、-Xmn 这些参数的含义:
答:堆内存分配:
JVM 初始分配的内存由-Xms 指定,默认是物理内存的 1/64;
JVM 最大分配的内存由-Xmx 指定,默认是物理内存的 1/4;
默认空余堆内存小于 40% 时,JVM 就会增大堆直到-Xmx 的最大限制;空余堆内存大于 70% 时,JVM 会减少堆直到 -Xms
的最小限制;
因此服务器一般设置-Xms、-Xmx 相等以避免在每次 GC 后调整堆的大小。对象的堆内存由称为垃圾回收器的自动内存管理系统回收。
非堆内存分配:
JVM 使用-XX:PermSize 设置非堆内存初始值,默认是物理内存的 1/64;
由 XX:MaxPermSize 设置最大非堆内存的大小,默认是物理内存的 1/4;
-Xmn2G:设置年轻代大小为 2G;
-XX:SurvivorRatio,设置年轻代中 Eden 区与 Survivor 区的比值。
3)垃圾回收算法有哪些?
答:引用计数 :原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数。垃圾回收时,只用收集计数为 0
的对象。此算法最致命的是无法处理循环引用的问题;
标记-清除 :此算法执行分两阶段。第一阶段从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除;
此算法需要暂停整个应用,同时,会产生内存碎片;
复制算法 :此算法把内存空间划为两个相等的区域,每次只使用其中一个区域。垃圾回收时,遍历当前使用区域,把正在使用中的对象复制到另外一个区域中;
此算法每次只处理正在使用中的对象,因此复制成本比较小,同时复制过去以后还能进行相应的内存整理,不会出现 “碎片”
问题。当然,此算法的缺点也是很明显的,就是需要两倍内存空间;
标记-整理 :此算法结合了 “标记-清除” 和 “复制”
两个算法的优点。也是分两阶段,第一阶段从根节点开始标记所有被引用对象,第二阶段遍历整个堆,把清除未标记对象并且把存活对象 “压缩”
到堆的其中一块,按顺序排放。
此算法避免了 “标记-清除” 的碎片问题,同时也避免了 “复制” 算法的空间问题。
4)root 搜索算法中,哪些可以作为 root?
答:被启动类(bootstrap 加载器)加载的类和创建的对象;
JavaStack 中的引用的对象 (栈内存中引用的对象);
方法区中静态引用指向的对象;
方法区中常量引用指向的对象;
Native 方法中 JNI 引用的对象。
5)GC 什么时候开始?
答:GC 经常发生的区域是堆区,堆区还可以细分为新生代、老年代,新生代还分为一个 Eden 区和两个 Survivor 区。
对象优先在 Eden 中分配,当 Eden 中没有足够空间时,虚拟机将发生一次 Minor GC,因为 Java 大多数对象都是朝生夕灭,所以
Minor GC 非常频繁,而且速度也很快;
Full GC,发生在老年代的 GC,当老年代没有足够的空间时即发生 Full GC,发生 Full GC 一般都会有一次 Minor GC。
大对象直接进入老年代,如很长的字符串数组,虚拟机提供一个;XX:PretenureSizeThreadhold
参数,令大于这个参数值的对象直接在老年代中分配,避免在 Eden 区和两个 Survivor 区发生大量的内存拷贝;
发生 Minor GC 时,虚拟机会检测之前每次晋升到老年代的平均大小是否大于老年代的剩余空间大小,如果大于,则进行一次 Full
GC,如果小于,则查看 HandlePromotionFailure 设置是否允许担保失败,如果允许,那只会进行一次 Minor
GC,如果不允许,则改为进行一次 Full GC。
6)内存泄漏和内存溢出
答:概念:内存溢出指的是内存不够用了;
内存泄漏是指对象可达,但是没用了。即本该被 GC 回收的对象并没有被回收;
内存泄露是导致内存溢出的原因之一;内存泄露积累起来将导致内存溢出。
内存泄漏的原因分析:长生命周期的对象引用短生命周期的对象;
没有将无用对象置为 null。
本篇文章是有为您呈现,希望给您带来更多更好的文章,请扫描下方二维码
方法区(线程共享):常量、静态变量、JIT(即时编译器) 编译后的代码也都在方法区;
带有final修饰符的类是不可派生的。在Java核心API中,有许多应用final的例子,例如java.lang.String,整个类都是final的。
在讨论这个问题之前,先考虑以下代码的输出结果
Copyright (C)
Tedu.cn All Rights Reserved 京ICP备号-56 达内时代科技集团有限公司 版权所有
选择城市和中心
达内北京亦庄大学生实训基地
达内北京网络营销中心
达内北京会计中心手机root是什么意思,root以后有什么缺点吗?root到底好吗?
按时间排序
手机root就是打开系统的最高root权限,也就是系统管理员权限。如果你没有root权限的话你就无法进行很多的操作,比如删除系统自带的某些软件(root过后也不要乱删,有可能导致无法开机)。
好处一:root之后可以删除一些不用或少用的的手机自带软件,避免那些软件启用后台更新占用了手机内存拖慢了手机运行速度。
好处二:许多应用软件都需要root之后才能使用的,root之后使用这些应用软件这更方便我们使用和管理手机。好处还是蛮多的,因为root之后成为superuser权力太大了,啥软件都可删除,所以使用的时候要注意点,以免删某些系统必须软件造成系统错误或者不稳定就不好了。
缺点是没有安全性,而且国行就没保修了。如果你不是什么手机发烧友或喜欢玩游戏的话不建议root,因为一般的功能足够使用了。
优点是可以精简手机内部程序,root后可以借助软件卸载掉手机自带程序,修改手机内部文件,但有些东西是不能删除也不能修改的,删除后出现异常会导致机子开不起机,无限重启等等。
优点显而易见,缺点也是一样,没有最高权限,机子运行速度慢,不能修改手机内部文件,不能实现拍照无声,RAM占率高,ROM空间少,但至少安全。
这也是为什么手机出厂时没有root的原因,不过总的来说root利大于弊。&
手机root后,手机的功能基本上都打开了获取了手机的最高权限,能卸载预装软件,更彻底干净清理手机空间什么的不过root后不能保修,但是它是可以解除的,所以root木有啥坏处通过应用宝来root是最好的,很稳定呢先在电脑端打开应用宝软件,然后提示连接手机——接着连接数据线——手机设置——开发者选项——USB调试打开——显示成功连接后——成功装好驱动了。进入工具箱——点击一键root就可以了,希望采纳。
感谢您为社区的和谐贡献力量请选择举报类型
经过核实后将会做出处理感谢您为社区和谐做出贡献
确定要取消此次报名,退出该活动?
请输入私信内容:鲁大师电脑版
硬件防护全面升级,全新官网为您领航
版本:5.15.18.1060
支持win2000以上的所有windows系统版本
鲁大师安卓版
一亿用户选择的手机性能评测大师
版本:8.6.5.18.0720
手机模拟大师
电脑玩手游,就用手机模拟大师
版本:4.1.
支持Vista以上的所有Windows系统版本
鲁大师电脑版
电脑性能评测
电脑硬件真伪辨别
电脑硬件安全防护和温度监控
鲁大师安卓版
手机性能评测
一键验证手机真假
手机降温、硬件垃圾清理、内存加速
手机模拟大师
电脑玩手机游戏
大屏键鼠操作快人一步
小号多开24小时随心挂机
鲁大师电脑版
电脑评测、监测、保护您的硬件安全
鲁大师游戏库
汇聚万款精品游戏 陪伴您的欢乐时光
小鸟动态壁纸 悦“动”于屏
手机模拟大师
电脑玩手游,就用手机模拟大师
鲁大师安卓版
一亿用户选择的手机硬件大师
智能省电方案,延长电池使用时间
手机智能芯片评测专家
解决手机使用“电脑、车载充电器、非原装充电器、充电宝”充电速度慢问题
作为鲁大师出品的二手电商品牌,是专注于二手数码产品销售的交易商城。买了联想a960。下载东西下载不上。总是说我手机/SD卡内存不足。求高手们教教我怎么root权限啊。_百度知道
买了联想a960。下载东西下载不上。总是说我手机/SD卡内存不足。求高手们教教我怎么root权限啊。
错了。错了。是A690.我晕。着急死了。...
错了。错了。是A690.我晕。着急死了。
答题抽奖
首次认真答题后
即可获得3次抽奖机会,100%中奖。
采纳数:29919
获赞数:37788
您好,根据您描述的情况可能是手机的存储或SD文件过多,建议把不必要的文件清理 以节省手机的利用空间。ROOT手机有风险,不建议您自行操作,如果在操作过程中出现错误,可能造成机器无法正常使用,甚至造成机器损坏,建议您联系服务站工程师为您检测处理下面是服务站的查询链接,您能查到详细地址以及联系方式手机服务站查询:
来自知道合伙人认证行家
数码类行家
采纳数:19969
获赞数:66392
山东理工大学工业设计系毕业生,潍坊巨鸣广告有限公司总经理。
一键root的方法root并没有想象中的那么难,目前有不少软件可以做到。像Z4root、UniversalAndRoot、GingerBreak和等root软件都比较方便。不过z4root也有许多不足的地方,z4root也不是全能,并不能支持所有的安卓手机进行root,不能使用z4root进行root的椒友们只能通过其它方法进行root了。教给椒友们的将是最简单的方法,使用root软件一键root:1、首先下载z4root软件并安装到手机中,安装完成后打开z4root软件。2、打开后将会出现两个选项,第一个是临时root,也就是reboot(重启)后就会还原回未root状态,第二个就是永久root了,使用第二个以后,我们重新开机也不再需要root权限了。3、选择一项进入后,软件就会自动对手机进行root,完全不用我们手工进行操作,非常得方便。4、经过一段时间的等待之后,如果成功的话,会在软件菜单中增加一个授权管理的图标,有了这个图标就表示我们的手机已经root成功了,现在你想怎么用就怎么用了。不过,软件法失败率也不低,一般情况下刷机法更为可靠,互联网上有各种机型的各种教程,因此通常情况下不建议使用软件法。
采纳数:19
获赞数:79
用户root软件刷啊
为你推荐:
其他类似问题
您可能关注的内容
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。1.什么是jvm?(1)jvm是一种用于计算设备的规范,它是一个虚构出来的机器,是通过在实际的计算机上仿真模拟各种功能实现的。(2)jvm包含一套字节码指令集,一组寄存器,一个栈,一个垃圾回收堆和一个存储方法域。(3)JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。JVM在执行字节码时,实际上最终还是把字节码解释成具体平台上的机器指令执行。
2.jdk、jre、jvm是什么关系?(1)JRE(Java Runtime Environment),也就是java平台。所有的java程序都要在JRE环境下才能运行。(2)JDK(Java Development Kit),是开发者用来编译、调试程序用的开发包。JDK也是JAVA程序需要在JRE上运行。(3)JVM(Java Virtual Machine),是JRE的一部分。它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。Java语言最重要的特点就是跨平台运行。使用JVM就是为了支持与操作系统无关,实现跨平台。
3.JVM原理(1)jvm是java的核心和基础,在java编译器和os平台之间的虚拟处理器,可在上面执行字节码程序。(2)java编译器只要面向jvm,生成jvm能理解的字节码文件。java源文件经编译成字节码程序,通过jvm将每条指令翻译成不同的机器码,通过特定平台运行。(JIT即时编译器Just-In-Time Compiler)
4. JVM执行程序的过程1) 加载.class文件 &具体参考:
2) 管理并分配内存&3) 执行垃圾收集JRE(java运行时环境)由JVM构造的java程序的运行环,也是Java程序运行的环境,但是他同时一个操作系统的一个应用程序一个进程,因此他也有他自己的运行的生命周期,也有自己的代码和数据空间。JVM在整个jdk中处于最底层,负责于操作系统的交互,用来屏蔽操作系统环境,提供一个完整的Java运行环境,因此也就虚拟计算机。操作系统装入JVM是通过jdk中Java.exe来完成,通过下面4步来完成JVM环境:1) 创建JVM装载环境和配置&2) 装载JVM.dll&3) 初始化JVM.dll并挂界到JNIENV(JNI调用接口)实例4) 调用JNIEnv实例装载并处理class类。5. JVM的生命周期1) JVM实例对应了一个独立运行的java程序它是进程级别&a) 启动。启动一个Java程序时,一个JVM实例就产生了,任何一个拥有public static void&main(String[] args)函数的class都可以作为JVM实例运行的起点&b) 运行。main()作为该程序初始线程的起点,任何其他线程均由该线程启动。JVM内部有两种线程:守护线程和非守护线程,main()属于非守护线程,守护线程通常由JVM自己使用,java程序也可以表明自己创建的线程是守护线程&c) 消亡。当程序中的所有非守护线程都终止时,JVM才退出;若安全管理器允许,程序也可以使用Runtime类或者System.exit()来退出&2) JVM执行引擎实例则对应了属于用户运行程序的线程它是线程级别的
&6、JVM内存模型
(1)java代码具体执行过程如下图,
(2)运行时数据区,即jvm内存结构图如下图
(3)运行时数据区存储了哪些数据?
  a) 程序计数器(PC寄存器)
    &&由于在JVM中,多线程是通过线程轮流切换来获得CPU执行时间的,因此,在任一具体时刻,一个CPU的内核只会执行一条线程中的指令,
  因此,为了能够使得每个线程都在线程切换后能够恢复在切 换 之前的程序执行位置,每个线程都需要有自己独立的程序计数器,并且不能互相被干扰,
  否则就会影响到程序的正常执行次序。因此,可以这么说,程序计数器是每个线程所私有的。由于程序计数器中存储的数据所占空间的大小不会随程序的执行而发生改变,
  因此,对于程序计数器是不会发生内存溢出现象(OutOfMemory)的。
  b) java栈
    & Java栈中存放的是一个个的栈帧,每个栈帧对应一个被调用的方法,在栈帧中包括局部变量表(Local Variables)、操作数栈(Operand Stack)、
    指向当前方法所属的类的运行时常量池(运行时常量池的概念在方法区部分会谈到)的引用(Reference to runtime constant pool)、
    方法返回地址(Return Address)和一些额外的附加信息。当线程执行一个方法时,就会随之创建一个对应的栈帧,并将建立的栈帧压栈。当方法执行完毕之后,便会将栈帧出栈。 
  c)本地方法栈
  本地方法栈与Java栈的作用和原理非常相似。区别只不过是Java栈是为执行Java方法服务的,而本地方法栈则是为执行本地方法(Native Method)服务的
  Java中的堆是用来存储对象本身的以及数组(数组引用是存放在Java栈中的)。堆是被所有线程共享的,在JVM中只有一个堆。
  e)方法区
  与堆一样,是被线程共享的区域。在方法区中,存储了每个类的信息(包括类的名称、方法信息、字段信息)、静态变量、常量以及编译器编译后的代码等。
  在Class文件中除了类的字段、方法、接口等描述信息外,还有一项信息是常量池,用来存储编译期间生成的字面量和符号引用。
  在方法区中有一个非常重要的部分就是运行时常量池,它是每一个类或接口的常量池的运行时表示形式,在类和接口被加载到JVM后,
  对应的运行时常量池就被创建出来。当然并非Class文件常量池中的内容才能进入运行时常量池,在运行期间也可将新的常量放入运行时常量池中,比如String的intern方法。
  7、JVM内存溢出的情况
  a)&程序计数器(Program Counter Register)
  每条线程都有一个独立的的程序计数器,各线程间的计数器互不影响,因此该区域是线程私有的。该内存区域是唯一一个在Java虚拟机规范中没有规定任何OOM(内存溢出:OutOfMemoryError)情况的区域。
  b)Java虚拟机栈(Java Virtual Machine Stacks)
    在Java虚拟机规范中,对这个区域规定了两种异常情况:
&&&  &1、如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常。
&&&&  2、如果虚拟机在动态扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常。
&&&&   & & 这两种情况存在着一些互相重叠的地方:当栈空间无法继续分配时,到底是内存太小,还是已使用的栈空间太大,其本质上只是对同一件事情的两种描述而已。
     & 在单线程的操作中,无论是由于栈帧太大,还是虚拟机栈空间太小,当栈空间无法分配时,虚拟机抛出的都是StackOverflowError异常,而不会得到OutOfMemoryError异常。
  & & & &  而在多线程环境下,则会抛出OutOfMemoryError异常。
  c)堆Java&Heap
    Java&Heap是Java虚拟机所管理的内存中最大的一块,它是所有线程共享的一块内存区域。几乎所有的对象实例和数组都在这类分配内存。Java&Heap是垃圾收集器管理的主要区域,因此很多时候也被称为&GC堆&。
&&&&  根据Java虚拟机规范的规定,Java堆可以处在物理上不连续的内存空间中,只要逻辑上是连续的即可。如果在堆中没有内存可分配时,并且堆也无法扩展时,将会抛出OutOfMemoryError异常。 &&
  d)方法区域,又被称为&永久代&,当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。
2、垃圾对象如何确定
Java堆中存放着几所所有的对象实例,垃圾收集器在对堆进行回收前,首先需要确定哪些对象还"活着",哪些已经"死亡",也就是不会被任何途径使用的对象。
引用计数法
引用计数法实现简单,效率较高,在大部分情况下是一个不错的算法。其原理是:给对象添加一个引用计数器,每当有一个地方引用该对象时,计数器加1,当引用失效时,计数器减1,当计数器值为0时表示该对象不再被使用。需要注意的是:引用计数法很难解决对象之间相互循环引用的问题,主流Java虚拟机没有选用引用计数法来管理内存。
可达性分析算法
这个算法的基本思路就是通过一系列的称为&GC Roots&的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连(用图论的话来说,就是从GC Roots到这个对象不可达)时,则证明此对象是不可用的。如图所示,对象object 5、object 6、object 7虽然互相有关联,但是它们到GC Roots是不可达的,所以它们将会被判定为是可回收的对象。
在Java语言中,可作为GC Roots的对象包括下面几种:
虚拟机栈(栈帧中的本地变量表)中引用的对象。
方法区中类静态属性引用的对象。
方法区中常量引用的对象。
本地方法栈中JNI(即一般说的Native方法)引用的对象。
现在问题来了,可达性分析算法会不会出现对象间循环引用问题呢?答案是肯定的,那就是不会出现对象间循环引用问题。GC Root在对象图之外,是特别定义的&起点&,不可能被对象图内的对象所引用。
对象生存还是死亡(To Die Or Not To Die)
即使在可达性分析算法中不可达的对象,也并非是&非死不可&的,这时候它们暂时处于&缓刑&阶段,要真正宣告一个对象死亡,至少要经历两次标记过程:如果对象在进行可达性分析后发现没有与GC Roots相连接的引用链,那它将会被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行finapze()方法。当对象没有覆盖finapze()方法,或者finapze()方法已经被虚拟机调用过,虚拟机将这两种情况都视为&没有必要执行&。程序中可以通过覆盖finapze()来一场"惊心动魄"的自我拯救过程,但是,这只有一次机会呦。
* 此代码演示了两点:
* 1.对象可以在被GC时自我拯救。
* 2.这种自救的机会只有一次,因为一个对象的finapze()方法最多只会被系统自动调用一次
* @author zzm
pubpc class FinapzeEscapeGC {
pubpc static FinapzeEscapeGC SAVE_HOOK = null;
pubpc void isApve() {
System.out.println("yes, i am still apve :)");
protected void finapze() throws Throwable {
super.finapze();
System.out.println("finapze mehtod executed!");
FinapzeEscapeGC.SAVE_HOOK = this;
pubpc static void main(String[] args) throws Throwable {
SAVE_HOOK = new FinapzeEscapeGC();
//对象第一次成功拯救自己
SAVE_HOOK = null;
System.gc();
//因为finapze方法优先级很低,所以暂停0.5秒以等待它
Thread.sleep(500);
if (SAVE_HOOK != null) {
SAVE_HOOK.isApve();
System.out.println("no, i am dead :(");
//下面这段代码与上面的完全相同,但是这次自救却失败了
SAVE_HOOK = null;
System.gc();
//因为finapze方法优先级很低,所以暂停0.5秒以等待它
Thread.sleep(500);
if (SAVE_HOOK != null) {
SAVE_HOOK.isApve();
System.out.println("no, i am dead :(");
运行结果为:
finapze mehtod executed!
yes, i am still apve :)
no, i am dead :(
接着说引用
无论是通过引用计数算法判断对象的引用数量,还是通过可达性分析算法判断对象的引用链是否可达,判定对象是否存活都与&引用&有关。在JDK 1.2以前,Java中的引用的定义很传统:如果reference类型的数据中存储的数值代表的是另外一块内存的起始地址,就称这块内存代表着一个引用。在JDK 1.2之后,Java对引用的概念进行了扩充,将引用分为强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)4种,这4种引用强度依次逐渐减弱。
& 强引用就是指在程序代码之中普遍存在的,类似&Object obj = new Object()&这类的引用,只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象。
& 软引用是用来描述一些还有用但并非必需的对象。对于软引用关联着的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收。如果这次回收还没有足够的内存,才会抛出内存溢出异常。在JDK 1.2之后,提供了SoftReference类来实现软引用。
& 弱引用也是用来描述非必需对象的,但是它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发生之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。在JDK 1.2之后,提供了WeakReference类来实现弱引用。
& 虚引用也称为幽灵引用或者幻影引用,它是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。在JDK 1.2之后,提供了PhantomReference类来实现虚引用。
软引用使用示例:
import java.lang.ref.SoftR
class Node {
pubpc String msg = "";
pubpc class Hello {
pubpc static void main(String[] args) {
Node node1 = new Node(); // 强引用
node1.msg = "node1";
SoftReference&Node& node2 = new SoftReference&Node&(node1); // 软引用
node2.get().msg = "node2";
System.out.println(node1.msg);
System.out.println(node2.get().msg);
输出结果为:
3、典型的垃圾回收算法
1.Mark-Sweep(标记-清除)算法
这是最基础的垃圾回收算法,之所以说它是最基础的是因为它最容易实现,思想也是最简单的。标记-清除算法分为两个阶段:标记阶段和清除阶段。标记阶段的任务是标记出所有需要被回收的对象,清除阶段就是回收被标记的对象所占用的空间。具体过程如下图所示:
从图中可以很容易看出标记-清除算法实现起来比较容易,但是有一个比较严重的问题就是容易产生内存碎片,碎片太多可能会导致后续过程中需要为大对象分配空间时无法找到足够的空间而提前触发新的一次垃圾收集动作。
2. Copying(复制)算法
为了解决Mark-Sweep算法的缺陷,Copying算法就被提了出来。它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用的内存空间一次清理掉,这样一来就不容易出现内存碎片的问题。具体过程如下图所示:
这种算法虽然实现简单,运行高效且不容易产生内存碎片,但是却对内存空间的使用做出了高昂的代价,因为能够使用的内存缩减到原来的一半。
很显然,Copying算法的效率跟存活对象的数目多少有很大的关系,如果存活对象很多,那么Copying算法的效率将会大大降低。
3. Mark-Compact(标记-整理)算法
为了解决Copying算法的缺陷,充分利用内存空间,提出了Mark-Compact算法。该算法标记阶段和Mark-Sweep一样,但是在完成标记之后,它不是直接清理可回收对象,而是将存活对象都向一端移动(美团面试题目,记住是完成标记之后,先不清理,先移动再清理回收对象),然后清理掉端边界以外的内存(美团问过)。具体过程如下图所示:
4.Generational Collection(分代收集)算法
分代收集算法是目前大部分JVM的垃圾收集器采用的算法。它的核心思想是根据对象存活的生命周期将内存划分为若干个不同的区域。一般情况下将堆区划分为老年代(Tenured Generation)和新生代(Young Generation),老年代的特点是每次垃圾收集时只有少量对象需要被回收,而新生代的特点是每次垃圾回收时都有大量的对象需要被回收,那么就可以根据不同代的特点采取最适合的收集算法。
目前大部分垃圾收集器对于新生代都采取Copying算法,因为新生代中每次垃圾回收都要回收大部分对象,也就是说需要复制的操作次数较少,但是实际中并不是按照1:1的比例来划分新生代的空间的,一般来说是将新生代划分为一块较大的Eden空间和两块较小的Survivor空间(一般为8:1:1),每次使用Eden空间和其中的一块Survivor空间,当进行回收时,将Eden和Survivor中还存活的对象复制到另一块Survivor空间中,然后清理掉Eden和刚才使用过的Survivor空间。
而由于老年代的特点是每次回收都只回收少量对象,一般使用的是Mark-Compact算法。
&5 新生代和老年代的区别(阿里面试官的题目):
**所谓的新生代和老年代是针对于分代收集算法来定义的,新生代又分为Eden和Survivor两个区。加上老年代就这三个区。数据会首先分配到Eden区 当中(当然也有特殊情况,如果是大对象那么会直接放入到老年代(大对象是指需要大量连续内存空间的java对象)。),当Eden没有足够空间的时候就会 触发jvm发起一次Minor GC。如果对象经过一次Minor GC还存活,并且又能被Survivor空间接受,那么将被移动到Survivor空 间当中。并将其年龄设为1,对象在Survivor每熬过一次Minor GC,年龄就加1,当年龄达到一定的程度(默认为15)时,就会被晋升到老年代 中了,当然晋升老年代的年龄是可以设置的。如果老年代满了就执行:Full GC 因为不经常执行,因此采用了 Mark-Compact算法清理
其实新生代和老年代就是针对于对象做分区存储,更便于回收等等**
关于垃圾回收算法(1)目前根据 Mark-Sweep算法 延伸出来了CMS算法(concurrent Mark-Sweep)算法
(2) G1(Garbage First)算法
这两个阿里的面试官问过他们的区别:
我做了整理:
参考资料:
阅读(...) 评论()}

我要回帖

更多关于 水肌澳产品有出问题吗 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信