Fork me on GitLab

了解JVM

  1:了解JVM是什么东西  

  做java开发基本都知道,JVM其实就是虚拟机。JVM是JRE的一部分。它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。Java语言最重要的特点就是跨平台运行。使用JVM就是为了支持与操作系统无关,实现跨平台。所以,JAVA虚拟机JVM是属于JRE的,而现在我们安装JDK时也附带安装了JRE(当然也可以单独安装JRE)。

  cmd进行控制台输入java -version命令可以看到本机的虚拟机信息。本文主要讲的是HotSpot。

 

   Java EE是以Java SE为基础的。所以并没有“JVM for Java EE”这么一说,只有“JVM for Java SE”,可以用于Java SE与Java EE。

  在这个类别下,主流选择有:(按流行程度递减)HotSpot VM  J9 VM  Zing VM     https://blog.csdn.net/lxlmycsdnfree/article/details/69286099

  从Java SE 7开始,HotSpot VM就是Java规范的“参考实现”(RI,Reference Implementation)。把它叫做“标准JVM”完全不为过。

  当大家说起“Java性能如何如何”、“Java有多少种GC”、“JVM如何调优”等等,经常默认说的就是特指HotSpot VM。可见其“主流性”。
(其实这不是件好事;具体到JVM实现才可以讨论的问题还是应该指明讨论是基于哪个实现)JDK8的HotSpot VM已经是以前的HotSpot VM与JRockit VM的合并版,也就是传说中的“HotRockit”,只是产品里名字还是叫HotSpot VM。这个合并并不是要把JRockit的部分代码插进HotSpot里,而是把前者一些有价值的功能在后者里重新实现一遍。移除PermGen、Java Flight Recorder、jcmd等都属于合并项目的一部分。

  不过要留意的是,这里我说的HotSpot VM特指“正常配置”版,而不包括“Zero / Shark”版。Wikipedia那个页面上把后者称为“Zero Port”。用这个版本的人应该相当少,很多时候它的release版都build不成功…

  2:JVM的体系结构

  

 

     

 

   3:类加载器

  加载class文件~

 

 

  1.虚拟机自带的加载器

  2.启动类(根)加载器

  3.应用程序加载器

  4.外边扩展加载器

  5.双亲委派(安全)机制 https://www.jianshu.com/p/1e4011617650

  4:沙箱安全机制

  我们都知道,程序员编写一个Java程序,默认的情况下可以访问该机器的任意资源,比如读取,删除一些文件或者网络操作等。当你把程序部署到正式的服务器上,系统管理员要为服务器的安全承担责任,那么他可能不敢确定你的程序会不会访问不该访问的资源,为了消除潜在的安全隐患,他可能有两种办法:

  1. 让你的程序在一个限定权限的帐号下运行。
  2. 利用Java的沙箱机制来限定你的程序不能为非作歹。以下用于介绍该机制。
  3. Java安全模型的核心就是Java沙箱(sandbox),什么是沙箱?沙箱是一个限制程序运行的环境。沙箱机制就是将 Java 代码限定在虚拟机(JVM)特定的运行范围中,并且严格限制代码对本地系统资源访问,通过这样的措施来保证对代码的有效隔离,防止对本地系统造成破坏。沙箱主要限制系统资源访问,那系统资源包括什么?——CPU、内存、文件系统、网络。不同级别的沙箱对这些资源访问的限制也可以不一样。
  4. 所有的Java程序运行都可以指定沙箱,可以定制安全策略。
  5. https://blog.csdn.net/qq_30336433/article/details/83268945

  5:Native,方法区 

  java的方法bai区在jdk7及以前是永久代,使用的是虚拟机的内存,du而到了zhijdk8,元空间取代了永久代,使用的是本地的内存dao。
Native Method是本地方法的意思,非java编写,比如c/c++,一般用于操作底层的硬件。在java中通过本地方法接口也就是带native修饰符的方法来调用本地方法。

  Native https://www.cnblogs.com/KingIceMou/p/7239668.html   

  方法区在JVM中也是一个非常重要的区域,它与堆一样,是被线程共享的区域。在方法区中,存储了每个类的信息(包括类的名称、方法信息、字段信息)、静态变量、常量以及编译器编译后的代码等。

  方法区(method area)只是JVM规范中定义的一个概念,用于存储类信息、常量池、静态变量、JIT编译后的代码等数据,具体放在哪里,不同的实现可以放在不同的地方。而永久代Hotspot虚拟机(常用)的特有的概念,是方法区的一种实现,别的JVM都没有这个东西。

  当一个classLoder启动的时候,classLoader的生存地点在jvm中的堆,然后它会去主机硬盘上将A.class装载到jvm的方法区,方法区中的这个字节文件会被虚拟机拿来new A字节码(),然后在堆内存生成了一个A字节码的对象,然后A字节码这个内存文件有两个引用一个指向A的class对象,一个指向加载自己的classLoader。那么方法区中的字节码内存块,除了记录一个class自己的class对象引用和一个加载自己的ClassLoader引用之外,还记录了什么信息呢?

 

   6:栈:数据结构的一种

  程序 = 数据结构加算法 。 提升自己

    程序 = 框架加业务逻辑。  恰饭用的

  栈:先进后出,后进先出。

  队列:先进先出。

  虚拟机栈:表示Java方法执行的内存模型,每调用一个方法就会为每个方法生成一个栈帧(Stack Frame),用来存储局部变量表、操作数栈、动态链接、方法出口等信息。每个方法被调用和完成的过程,都对应一个栈帧从虚拟机栈上入栈和出栈的过程。虚拟机栈的生命周期和线程是相同的。栈不会存在垃圾回收

  栈溢出的错误实例     https://www.cnblogs.com/panxuejun/p/5882424.html

public class Test {
    public static void main(String[] args) {
        a();
    }
    public static void a(){
        test();
    }
    public static void test(){
        a();
    }
}

Exception in thread "main" java.lang.StackOverflowError
    at mydemo.Test.test(Test.java:12)
    at mydemo.Test.a(Test.java:9)
    at mydemo.Test.test(Test.java:12)
    at mydemo.Test.a(Test.java:9)
    at mydemo.Test.test(Test.java:12)
    at mydemo.Test.a(Test.java:9)
    at mydemo.Test.test(Test.java:12)
    at mydemo.Test.a(Test.java:9)
    at mydemo.Test.test(Test.java:12)
    at mydemo.Test.a(Test.java:9)
    at mydemo.Test.test(Test.java:12)
    at mydemo.Test.a(Test.java:9)
    at mydemo.Test.test(Test.java:12)
    at mydemo.Test.a(Test.java:9)
    at mydemo.Test.test(Test.java:12)
    at mydemo.Test.a(Test.java:9)
    at mydemo.Test.test(Test.java:12)
    at mydemo.Test.a(Test.java:9)
    at mydemo.Test.test(Test.java:12)
    at mydemo.Test.a(Test.java:9)
    at mydemo.Test.test(Test.java:12)
    at mydemo.Test.a(Test.java:9)
    at mydemo.Test.test(Test.java:12)
    at mydemo.Test.a(Test.java:9)
    at mydemo.Test.test(Test.java:12)

 

 

   7.堆

  Heap,一个JVM只有一个堆内存,堆内存大小是可以调节的。

  类加载器读取文件后一版会把class 方法 常量.....放入堆中。

     https://blog.csdn.net/u013728021/article/details/84034420

  堆内存中细分为三大区域,

    1.新生区(伊甸园区)

      类诞生和成长的地方 甚至死亡

      所有的对象都是在新生区new出来的

      在java中有90%的对象都是临时对象

    2.养老区

    3.永久储存区

    这个区域常驻内存,用来存放JDK自代的类,这个区域不存在垃圾,关闭JVM就会释放这个区域的内存。

      JDK1.6之前:永久代,常量池是在方法区

      JDK1.7:永久代,但是在慢慢退化,去永久代,常量池在堆中

      JDK1.8:无永久代,常量池在元空间。

  GC垃圾回收主要是在新生区(伊甸园区)和养老区

  假设内容满了,OMM,堆内存不够。在JDK8之后永久储存区改名为元空间

    7.MAT、Jprofiler工具的作用

  1.分析Dump内存文件、快速定位内存泄露

   2.获得堆中的数据

  ......................

  

 

  

  

 

posted @ 2020-08-19 10:43  隐琳琥  阅读(198)  评论(0编辑  收藏  举报