• JVM 原理


    引言

       JVM一直是java知识里面进阶阶段的重要部分,如果希望在java领域研究的更深入,则JVM则是如论如何也避开不了的话题,本系列试图通过简洁易读的方式,讲解JVM必要的知识点。

    运行流程

      java代码通过编译之后生成字节码文件(class文件),通过:java HelloWorld执行,此时java根据系统版本找到jvm.cfg,再通过jvm.cfg文件找到对应的jvm.dll,jvm.dll则是java虚拟机的主要实现;初始化jvm,获取java本地接口,然后找到main方法,最后执行。详见下图

    内存空间

      JVM内存空间包含:方法区、java堆、java栈、本地方法栈。

      方法区:是各个线程共享的区域,存放类信息、常量、静态变量。

      java堆:是线程共享的区域,我们的类的实例就放在这个区域,可以想象你的一个系统会产生很多实例,因此java堆的空间也是最大的。如果java堆空间不足了,程序会抛出OutOfMemoryError异常。内存溢出

      java栈:是每个线程私有的区域,它的生命周期与线程相同,一个线程对应一个java栈,每执行一个方法就会往栈中压入一个元素,这个元素叫“栈帧”,而栈帧中包括了方法中的局部变量、用于存放中间状态值的操作栈。

      本地方法栈:java栈类似,只不过它是用来表示执行本地方法的,本地方法栈存放的方法调用本地方法接口,最终调用本地方法库,实现与操作系统、硬件交互的目的。

      PC寄存器:程序执行的顺序,控制程序指令的执行顺序

      执行引擎:根据PC寄存器调配的指令顺序,依次执行程序指令。

    内存溢出

      1. OutOfMemoryError:PermGen space(源程序中使用大量的jar或class)

        a、增加java虚拟机中的XX:PermSize和XX:MaxPermSize参数的大小;在catalina.sh 或catalina.bat文件中一系列环境变量名说明结束处(大约在70行左右) 增加一行: JAVA_OPTS=" -XX:PermSize=64M -XX:MaxPermSize=128m"

        b、清理应用程序中lib下的jar包

      2. OutOfMemoryError:Java heap space(java虚拟机创建的对象太多)

        a、检查程序是否有死循环或创建大量对象。

        b、增加Java虚拟机中Xms(初始堆大小)和Xmx(最大堆大小)参数的大小。如:set JAVA_OPTS= -Xms256m -Xmx1024m

      3. OutOfMemoryError:unable to create new native thread(JVM已经被系统分配了大量的内存,并且它至少要占用可用内存的一半)

        a、jvm参数中添加-Xss128k将线程栈内存大小设置为128k

    JVM配置参数

      JVM配置的参数分为三种:跟踪参数、堆分配参数、栈分配参数

    跟踪参数

      1、当发生GC(垃圾回收)时,打印GC简要信息

      使用-XX:+PrintGC或-verbose:gc参数

      2、打印GC的详细信息以及堆使用详细信息

      使用-XX:+PrintGCDetails参数

      3、使用外部文件记录GC的日志

      使用-Xloggc:log/gc.log

      4、监控类的加载

      使用-XX:+TraceClassLoading

    堆配置参数

      指定最大堆,最小堆:Xmx、Xms

        -Xms等价于-XX:InitalHeapSize 表示堆内存初始大小

        -Xmx等价于-XX:MaxHeapSize 表示最大堆内存大小,可使用jinfo -flag MaxHeapSize 进程id查看

        -Xss等价于-XX:InitalStackSize 表示线程栈的初始大小,可以使用jinfo -flag ThreadStackSize 进程id查看,

      最大堆也就是Xmx参数指定的大小,表示java程序最大能使用多少内存大小,如果超过这个大小,那么java程序会报:out of memory(内存溢出)

      堆分配参数的总结

      永久区分配参数:-XX:PermSize -XX:MaxPermSize

      栈大小分配参数:栈大小参数为-Xss,通常只有几百k,决定了函数调用的深度,每个线程都有自己独立的栈空间。如果函数调用太深,超过了栈的大小,则会抛出java.lang.StackOverflowError,通常我们遇到这种错误,不是去调整-Xss参数,而是应该去调查函数调用太深的原理,是否使用递归,能不能保证递归出口等。

    垃圾回收算法

      java语言与C语言最大的区别就是内存自动回收

      垃圾回收算法:1、引用计数法;2、标记清除

      垃圾回收器:

        1. 串行收集器:-XX:+UseSerialGC

        2. 并行回收器:

          a、ParNew回收器:-XX:+UseParNewGC

          b、Parallel回收器:-XX:+UseParallelGC

        3. CMS回收器:-XX:+UseConcMarkSweepGC

        4. G1回收器:-XX:+UseG1GC

     JDK与JRE的区别

      Java 运行时环境(JRE-Java Runtime Environment),它包括 Java 虚拟机、Java 核心类库和支持文件,但并不包含开发工具(JDK-Java Development Kit)——编译器、调试器和其他工具。

      Java 开发工具包(JDK)是完整的 Java 软件开发包,包含了 JRE,编译器和其他的工具(比如 JavaDoc, Java 调试器),可以让开发者开发、编译、执行 Java 应用程序。

  • 相关阅读:
    前端总结挺全面的
    cmd与bat脚本的使用
    Spring控制反转(IoC)的理解
    C# 中迭代器
    URL 分页并排序
    结合Flash上传文件时显示进度条
    C# 语言特性
    where T:new()
    图片缩放特效
    C# 隐藏窗体 ALT+TAb不可见
  • 原文地址:https://www.cnblogs.com/huanghzm/p/11024592.html
Copyright © 2020-2023  润新知