美文网首页互联网架构
最新京东面试题四(修正版4.0)

最新京东面试题四(修正版4.0)

作者: Java架构师CAT | 来源:发表于2019-05-21 18:04 被阅读0次

    JVM的新特性

    使用Metaspace(元空间)(JEP 122)代替持久代(PermGen space)。在JVM参数方面,使用-XX:MetaSpaceSize和-XX:MaxMetaspaceSize代替原来的-XX:PermSize和-XX:MaxPermSize。

    元空间的本质和持久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制,但可以通过以下参数来指定元空间的大小:

    -XX:MetaspaceSize,初始空间大小,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize时,适当提高该值。

    -XX:MaxMetaspaceSize,最大空间,默认是没有限制的。

    除了上面两个指定大小的选项以外,还有两个与 GC 相关的属性:

    -XX:MinMetaspaceFreeRatio,在GC之后,最小的Metaspace剩余空间容量的百分比,减少为分配空间所导致的垃圾收集

    -XX:MaxMetaspaceFreeRatio,在GC之后,最大的Metaspace剩余空间容量的百分比,减少为释放空间所导致的垃圾收集

    结论

    通过为开发者提供很多能够提高生产力的特性,Java 8使得Java平台前进了一大步。现在还不太适合将Java 8应用在生产系统中,但是在之后的几个月中Java 8的应用率一定会逐步提高(PS:原文时间是2014年5月9日,现在在很多公司Java 8已经成为主流,我司由于体量太大,现在也在一点点上Java 8,虽然慢但是好歹在升级了)。作为开发者,现在应该学习一些Java 8的知识,为升级做好准备。

    关于Spring:对于企业级开发,我们也应该关注Spring社区对Java 8的支持,可以参考这篇文章——Spring 4支持的Java 8新特性一览

    http://blog.csdn.net/yczz/article/details/50896975

    实际项目的服务(几台机器)

    p2p: 2台服务器; 电脑上的网站;

    h5: 2台服务器; 手机浏览器访问的

    App: 接口项目,3台服务器; android和ios开发的一个客户端,需要安装;

    分布式:

    Dubbo服务: 3台;

    fastdfs: 4台机器, 2Group,每个group里面是两台机器;

    Nginx: 2台服务器, 静态资源访问; 动静分离,

    redis:3台服务器;

    数据库db: 2台,主从

    定时任务: 2台;

    合同生成: 2台;

    后台项目: 2台;

    支付: 2台;

    短信:2台;

    三方接口. zookeeper : 3台;

    营销活动其他 : 3台;

    对账系统;

    红包系统;

    数据挖掘;

    37台机器

    订单查询 充值自己思路最重要

    JVM

    既然说到了JVM,说说你对垃圾回收的理解

    而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾。JVM的一个系统级线程会自动释放该内存块。垃圾收集意味着程序不再需要的对象是"无用信息",这些信息将被丢弃。当一个对象不再被引用的时候,内存回收它占领的空间,以便空间被后来的新对象使用。事实上,除了释放没用的对象,垃圾收集也可以清除内存记录碎片。由于创建对象和垃圾收集器释放丢弃对象所占的内存空间,内存会出现碎片。碎片是分配给对象的内存块之间的空闲内存洞。碎片整理将所占用的堆内存移到堆的一端,JVM将整理出的内存分配给新的对象。

    垃圾收集器对堆中的对象进行回收前,要先确定这些对象是否还有用,判定对象是否为垃圾对象有如下算法:

    1、 引用计数法

    引用计数是垃圾收集器中的早期策略。在这种方法中,堆中每个对象(不是引用)都有一个引用计数。对于一个对象 A,只要有任何一个对象引用了 A,则A 的引用计数器就加 1,当引用失效时,引用计数器就减 1。只要对象 A 的引用计数器的值为 0,则对象 A就不可能再被使用。

    引用计数法实现简单,判定效率也很高。但是这个算法有明显的缺陷,对于循环引用的情况下,循环引用的对象就不会被回收。如A=B,B=A, 此时,对象 A 和对象B 的引用计数器都不为 0。但是在系统中却不存在任何第 3 个对象引用了 A 或 B。也就是说,A 和 B 是应该被回收的垃圾对象,但由于垃圾对象间相互引用,从而使垃圾回收器无法识别,引起内存泄漏。

    2、 根搜索算法

    这种算法的基本思路是通过一系列名为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,就证明此对象是不可用的。在Java语言里,可作为GC Roots的对象包括下面几种:

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

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

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

    本地方法栈中JNI(Native方法)的引用对象。

    3、引用的类型

    无论是通过引用计数算法判断对象的引用数量,还是通过根搜索算法判断对象的引用链是否可达,判断对象是否存活都与“引用有关”。一般的引用类型分为强引用( Strong Reference)、软引用( Soft Reference)、弱引用( Weak Reference)、虚引用( Phantom Reference)四种,这四种引用强度依次逐渐减弱。

    1、强引用就是指在程序代码之中普遍存在的,类似“Objectobj = new Object()”这类的引用,只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。如果不使用时,可以赋值obj=null,显示的设置ob为null,则gc认为该对象不存在引用,这时候就可以回收此对象。

    四、垃圾收集算法

    1、标记-清除算法(Mark-Sweep)

    标记-清除算法分为标记和清除两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象,标记过程其实就是根搜索算法判断对象是否存活。该算法主要不足有两个:一个是效率问题,标记和清除两个过程的效率都不高;另一个是空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大的对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。标记-清除算法的执行过程如下图所示:

    2、复制算法(Coping)

    复制算法是把内存分成大小相等的两块,每次使用其中一块,当垃圾回收的时候,把存活的对象复制到另一块上,然后把这块内存整个清理掉。这样使得每次都是对整个半区进行内存回收,内存分配时就不用考虑内存碎片等复杂情况,实现简单,运行高效。这种方法适用于短生存期的对象,持续复制长生存期的对象则导致效率降低。复制算法的执行过程如下图所示:

    3、 标记-整理算法(Mark-Compact)

    复制算法在对象存活率较高时就要进行较多的复制操作,效率将会降低。老年代更常见的情况是大部分对象都是存活对象。如果依然使用复制算法,由于存活的对象较多,复制的成本也将很高。标记-整理算法是一种老年代的回收算法,该算法与标记-清除算法的标记过程一样,但是之后不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。这种方法既避免了碎片的产生,又不需要两块相同的内存空间,其性价比比较高。该算法示意图如下图所示:

    4、 分代收集算法

    根据垃圾回收对象的特性,不同阶段最优的方式是使用合适的算法用于本阶段的垃圾回收,分代算法即是基于这种思想,它将内存区间根据对象的特点分成几块,根据每块内存区间的特点,使用不同的回收算法,以提高垃圾回收的效率。一般把java堆分为新生代和老年代,新生代采用复制算法,老年代采用标记-整理算法。

    同时要注意finalize()方法是Java的缺省机制,有时为确保对象资源的明确释放,可以编写自己的finalize方法。


    进架构师群693845731,与大佬共同交流,免费领取架构师资料

    关注微信公众号动力节点Java资源库,回复【 jgs 】即可免费领取系列学习资料、


    相关文章

      网友评论

        本文标题:最新京东面试题四(修正版4.0)

        本文链接:https://www.haomeiwen.com/subject/iefszqtx.html