美文网首页
2018-07-20-关于JVM学还是不学

2018-07-20-关于JVM学还是不学

作者: ohcomeyes | 来源:发表于2018-11-02 12:32 被阅读0次

前言

说起JVM大多数给予的回应是JAVA虚拟机,是JAVA语言跨平台的武器。而且我们在开发中遇到和JVM有关的问题基本上就是OutOfMemoryError(内存溢出),然后一般解决方法就是找到相关的代码进行优化或者调整-Xms(初始内存)和-Xmx(最大能够使用内存大小)。尤其现在很多语言、框架概括来说就是以特有的方式抽象出来,隐藏具体的细节实现。那关于底层的这块学还是不学呢?

误区

其实很多人在谈论到JVM的时候没有一个很清晰的认识,而且不常用到,所以会有要不要学的必要!
一方面觉得接触到底很厉害,一方面又觉得用不着,不是有句话说,不以结婚为目的谈恋爱都是在耍流氓。其实是一个道理,所有的底都是在为上层服务,学不学取决于工作和个人,如果单纯只是觉得学了很厉害,这个就是在扯蛋了,毕竟就算学完JVM还有操作系统核心以及cpu指令这些更底层的东西。
所有建议要了解JVM,但根据实际情况再考虑要不要深究。

掌握的好处

  • 更清晰:目前很多高级语言都是解释型语言,但谈到JAVA的时候就可以说是解释与编译并存语言,JVM中解释器以及即时编译器就可以回答这个问题。
  • 更理解:理解动态编译和静态编译的区别,我们都知道常通过 javac 将程序源代码编译,转换成 java 字节码,JVM 通过解释字节码将其翻译成对应的机器指令,逐条读入,逐条解释翻译,JVM JIT(即时编译编译器)会把翻译过的机器码保存起来,以备下次使用,提高执行效率。
  • 更高效:能够清楚Java应用在运行时堆的布局情况,观察gc频率优化内存的分配策略,通过调整JVM相关参数提高Java应用的性能。
  • 更明白:知道Java程序是如何执行的,为什么具备可移植性强的特性。

JVM架构图

JVM = 类加载器(Classloader) + 执行引擎( Execution Engine) + 运行时数据区域 (Runtime Data Areas)


JVM-Architecture

如果看的迷糊,就先看看翻译过来的吧,建议相关的计算机单词还是要掌握的


JVM架构图

类加载器(Classloader)

  1. 装载:查找和导入class文件
    查找的时候通过启动类(classpath下)、扩展类(jre\lib下)、应用程序类(自定义的类),加载时会有委派分层算法,通常我们见到的就是双亲委派模型。
    双亲委派:每次通过先委托父类加载器加载,当父类加载器无法加载(没有)时,再自己加载。源码ClassLoader类的loadClass方面就默认实现,感兴趣的可以去看看,要说有啥作用,其实个人理解一方面避免了重复加载,一方面安全一些,好比自定义String类动态加载替换了核心类,那要是在里面植入不安全代码怎么处理。

  2. 链接:把类的二进制数据合并到JRE中

  3. 校验:检查载入class文件数据的正确性

  4. 准备:给类的静态变量分配存储空间,并设置默认值

  5. 解析:将符号引用转变成直接引用

  6. 初始化:最后阶段,所有的静态变量将被分配原始值,静态块将被执行。

Java的动态类加载功能由类加载器处理的,有两种装载class的方式

  • 隐式:new方式生成对象时,隐式调用classLoader到JVM
  • 显式:通过class.forname()动态加载

运行时数据区域 (Runtime Data Areas)
主要被分为5个模块

  1. 方法区:各个线程共享的内存区域,所有的类级数据将被存储在这里,包括静态变量,通过class对象调用方法获取信息的时候,那些数据都是来自这里,每个JVM只有一个方法区。
  2. 堆区:各个线程共享的内存区域,存储对象实例以及数组值,由于方法区和堆区共享多个线程的内存,所以存储的数据不是线程安全的,每个JVM只有一个堆区。由后面说到的GC自动管理,堆区会分成两块:新生代New Generation和旧生代Old Generation,可以动态扩展,像上面说的内存溢出啊,设置这个(-Xms和-Xmx)。
    堆区
  1. 栈区:每个线程都会创建一个独立的栈区,当每个方法调用时会在栈区创建一个栈帧(条目),用于存储局部变量表、操作栈、动态链接、方法出口等信息,方法的调用到执行完成可以看成是以栈帧为单位,进行压栈和出栈,因为不是共享内存,所以是线程安全的。看图:
    栈区
  2. 程序计数器(PC):每个线程都有一个独立的PC,可以理解为PC是执行的字节码指令的指示器,告诉你下一条指令是哪个,PC是存储在计算机处理器的内部,而且JAVA应用是控制不了的,但是字节码解析器可以通过控制PC的值来选择下一条要执行的字节码指令,这样就能完成分支、循环、跳转、异常处理、线程恢复等基础功能。
  3. 本地方法栈:保存了本地方法信息,和栈区一样,每一个线程,将创建一个单独的本地方法栈。为本地(Native)方法服务。

执行引擎( Execution Engine)
执行运行时数据区 (Runtime Data Areas)分配的字节码,或者执行本地方法。

  1. 解析器:解析字节码
  2. 即时编译编译器(JIT):提高性能的东西,因为每个方法重复调用的话解析器需要重新去解析,而解析器解析字节码发现重复的时候可以丢给JIT,JIT来把它生产本地方法,供重复调用。里面的分析器就是一个探查器,用来发现某个方法被多次调用或者未被调用。
  3. 垃圾回收器(GC):这个东西大家应该听的挺多的把,就是用来内存回收的,主要是管理堆区,针对堆区的新生代和旧生代都由不同的回收机制。具体的回收技术感兴趣的可以去了解一些,比较高级,可以针对不同环境选择不同机制。
  4. 本地方法接口(JNI):JNI将和本地方法库相互作用,为执行引擎提供需要。
  5. 本地方法库:执行引擎所需的本地库的集合。

结语

关于里面一些详细以后再慢慢补充吧,毕竟对整个的架构有了一定了解后,对个人在设计方面以及在优化方面还是有帮助的~
个人博客~
简书~

相关文章

  • 2018-07-20-关于JVM学还是不学

    前言 说起JVM大多数给予的回应是JAVA虚拟机,是JAVA语言跨平台的武器。而且我们在开发中遇到和JVM有关的问...

  • 学还是不学

    原创图文 今天早上锻炼时,我一小学的同学过来了,她在那挖土,准备带回去种菜,她是练太极的。我就问她,你那练太极收钱...

  • 挣扎的痛苦

    学还是不学,脑海中的撕杀,学还不好,不学又无正事,挣扎,喘息……学!加油!

  • 英语:学还是不学?

    谈起英语学习,很多人的感情是复杂的,可以说对英语既喜欢又无奈。喜欢,是因为作为一门语言,英语有其独特的魅力,用处非...

  • 学还是不学呢

    突然发现,用纯音乐来学习对于我来说,是个很愚蠢的决定。 它使我的内心更加的躁动,外面的鸟鸣声,屋内的音乐声是我更加...

  • 英语语法,学还是不学,这不是个问题!

    关于英语语法的学习,一直争议不断,不仅是怎样学的问题,就连学还是不学,都没有统一的看法。 本文的看法是:要学,而且...

  • Kotlin 学?不学?学?不学?......

    没想到Kotlin让Android开发社区沸腾了,一夜之间各种入门到精通的教程都有了,好多兄弟跑来问Kotlin的...

  • 学还是不学?是个问题

    今天,一个位好友问我,有没有听过全脑开发?我说听过。 “你要让你女儿去开发?”我问她。 “今天去试听了一下,正在纠...

  • 你还在犹豫学还是不学?

    柚子是我的好朋友,她总是说想要过自己喜欢的生活,当你问她什么是她喜欢的生活的时候,她又说不知道。 “不知道”是她的...

  • 太厉害了!阿里架构大牛用一份662页的PDF文档把虚拟机讲明白了

    对于面试来说JVM知识是大厂必问的,你不会你就大概率被PASS,你说你学不学?对于平时工作来说,万一遇到内存异常的...

网友评论

      本文标题:2018-07-20-关于JVM学还是不学

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