JAVA与JVM

作者: 靈08_1024 | 来源:发表于2018-05-08 15:16 被阅读38次

    JVM(JAVA虚拟机)

    虚拟机分为栈和堆:

    • 堆:
      回收:堆是由GC来负责回收的。
      存储类型:主要存储对象、静态成员变量随类的类型一起存储在对上。
      存储大小:堆是动态生成内存大小。
      存储周期:生存期无需通知编译器。
      存取效率:存取慢。
    • (线程)栈:
      回收:线程执行完自动回收。
      存储类型:栈中主要存储基本类型变量(小写的int等类型)、调用栈和本地变量。数据共享。
      存储大小:生成数据大小确定。
      存储周期:生存期确定。
      存取效率:存取快。

    Tips:1、如果两个线程(中的本地变量)调用了同一个对象,那么他们都会拥有这个变量的私有拷贝。

    1. 在web环境中,Tomcat启动会占用一个线程,而用户每次访问API,Tomcat会额外创建一个线程。

    JMM(JAVA内存模型)

    JMM是指JVM对于内存是如何操作的一个规范。

    1. JMM规定了一个线程何时如何看到修改后共享变量的值,以及在必须时,如何同步的访问共享变量。它要求调用栈和本地变量存放在线程栈上,对象存放在堆上,线程间的通信必须要经过主内存。它定义了8个基础操作。
    操作规则
    1. 一个变量在同一时刻,只允许一条线程对其执行Lock操作,而该线程可以对该变量执行n次Lock,如果需要unlock,则同样需要执行n次。
    2. 如果一个变量执行了锁(包括synchronized和Lock等)操作,那么他会清空工作内存中的值,在执行引擎使用此变量之前,需要重新执行load或者assign来初始化值。
    3. 若一个变量没有被lock,则不允许执行unlock。也不允许执行其他线程的unlock。
    4. 在执行解锁操作之前,必须先把该值同步回主内存。
    5. read和load操作,可以不连续执行,但必须先后执行。同理于store和write操作。

    classloader(类加载机制)

    1. 类加载的方式
    • 显式:通过Class.forName("XXX")来加载;
    • 隐式:通过new来隐式调用classLoader到JVM;

    在类的加载过程中,所有类都是从父类采用 双亲委派原则 加载过去的(而不是直接去加载这个类的)。有三个最基本的父类加载器Bootstrap class loader(所有类的父类加载器,包括后面两个)、extension class loader、application class loader。

    Bootstrap class loader:加载基本的jdk包。
    extension class loader:加载第三方jar包。
    application class loader:加载应用程序和用户自定义类。
    双亲委派原则:

    其工作流程为:

    1. 从已经加载过的类中查找是否加载过此类,若加载过则直接返回;
    2. 若未加载,则委托父类加载器去加载,层层委托,直到最顶层的父类;
    3. 若所有的父类加载器都不能加载该类时,由当前类自己加载,并放入自己的缓存中。

    采用这种形式的加载,主要是基于安全,避免两个同名的类加载冲突。

    GC(回收机制)

    什么是GC

    GC即垃圾回收。对于程序中不可达的引用或者变量等进行资源回收。

    GC的常用算法

    1. 计数法
    所有的变量从一出生就被标记了使用次数,出生标记起始数字start,在该线程中,每一次使用会记录次数+1,每一次用完会减1,若最后减为end(变量达到死亡的数值),回收该变量。
    优点:使用简单,每个对象分配一个计数器。
    缺点:对于循环或递归效果很差。
    2. 标记-清除法
    停止所有工作,标记扫描过的活跃的对象,然后将没有标记的清除掉。
    优点:可以解决循环问题。
    缺点:1 所有都要停止;2 当对象很多时,效率不高;3 造成内存碎片。

    Tips:内存碎片,即内存中断断续续存在的部分。每个一段会有一段内存,这样会导致申请大对象时,无法申请。

    3. 复制法
    开辟两块空间,某一时刻只有一个空间活跃,当活跃的空间快满时,将活跃空间里的活对象移动到不活跃的空间中,此时不活跃的空间升为活跃。较于标记-清除法来说以空间换时间。

    优点:1 不用停止;2 只扫描活对象;3 没有碎片化。
    缺点:1 空间开销大;2 复制开销。

    4. 标记-整理法
    该方法时汲取于清理法复制法。首先扫描所有活跃的对象,并标记所有活跃的对象,然后清除未标记的对象,并将活跃的的对象复制到堆得底部。

    优点:1 不用停止;2 只扫描活对象;3 没有碎片化;4 没有空间开销。
    缺点:1 复制开销。

    JAVA与GC

    java中的GC没有指定的用法,有可能以上都用到。
    java中还存有一种方法分代收集法。针对于指定的区域进行回收。可以缩小收集范围,一块一块收。涉及到的GC有:
    Minor GC:也叫young GC。
    作用范围:年轻代空间(Eden和Survivor区域)
    算法:标记-整理法。
    触发条件:1 young gen满了
    2 要分配的对象大于剩余空间;
    Major GC:也叫old GC。
    作用范围:老年代。
    触发条件:1 old gen满了
    Full GC:包含Minor GC和Major GC。
    作用范围:整个堆——年轻代和老年代。
    触发条件:1 如果young GC的平均晋升大小比old gen的剩余大小大

    内存泄漏和内存溢出

    内存泄漏:memory leak。是指堆内存由于某种原因,无法释放或未释放,造成系统资源的浪费。
    内存溢出:即OOM(OutOfMemory)。程序在申请内存时,没有空间供其使用,或已申请的内存小于要使用的内存。

    优化

    一般设置Xmx和Xms一样。
    Xss为每个线程的大小。默认为1M。在相同物理内 存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。
    Xmn大小推荐为整个堆的3/8。
    参考:常用 JVM 命令参数
    设置JVM参数,查看堆大小

    JMM参考:https://www.jianshu.com/p/be923a7beb2c

    参考:https://blog.csdn.net/lzxadsl/article/details/50159939

    相关文章

      网友评论

        本文标题:JAVA与JVM

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