JVM

  

1,虚拟机得发展

  1)HostSpot VM(sun)

     以前使用范围最广的java虚拟机

  2)  JRockit VM(BEA)

      号称“世界上最快的Java虚拟机”

       3)  Dalvik VM(Google)及区块链/GoLang

  4) HostSpot  VM(ORACLE)

    目前世界用的最广的java虚拟机

      模块化----->混合语言------>多核并行------>丰富语言------>64位------>更强垃圾回收

    java11的垃圾回收ZGC,回特别快,基本是在10ms之内

    openJDK与Oracle开发的99%一样 ,但是openJDK是免费的

2,JVM的整体

      

    内存是jvm的五脏六腑

    1)内存分配

    2) 垃圾回收

 3.运行时数据区

  JVM在运行过程中会把它所管理的内存划分成若干不同的数据区域

  私有线程:程序计数器,虚拟机栈,本地方法栈

  共享线程:堆,方法区

4.程序计数器(唯一不会OOM)

  指向当前线程正在执行的字节码指令的地址(行号)

  为什么需要程序计数器?

 1,java是多线程的,意味着线程切换确保多线程情况下的程序正常执行

 

 

 5.栈:数据结构

  入口和出口只有一个

  特点:先进后出

  为什么要JVM使用栈

 

 

 

 

 6.虚拟机栈

  虚拟机栈(大小设置 -Xss 1M)

    储存当前线程运行方法所需要的数据,指令返回地址

    什么时候需要调整虚拟机栈的大小?

      要创建大量线程的时候,值要变小,因为内存就那么大,调小才能变多

 

 

    栈帧

      每个方法在执行的同时都会创建一个栈帧

    栈帧主要包括:

      1.局部变量表

      2.操作数栈

      3.动态连接

      4.返回地址

 

    方法会打包栈帧,放到虚拟机的栈中,每个方法都会创建栈帧,栈 顶一顶是虚拟机正在执行

7.本地方法 栈

    本地方法栈保存的是native方法的信息,当一个JVM创建的线程调用native方法后JVM不再为其在

    虚拟机栈中创建栈帧,JVM只是简单的动态链接并直接调用native方法

    虚拟机规范无强制规定,各版本虚拟机自由实现HostSpot直接把本地方法栈和虚拟机栈合二为一

 

8.线程共享的区域

  方法区(永久代(JDK1.7和以前),元空间(JDK1.8))

    1),类信息

    2),常量

    3),静态变量

    4).变异后的代码

  Java堆(-Xms;-Xmx;-Xmn)

      -Xms:最小     -Xmx:最大     -Xmn:新生代大小

      -Xm256M  大小是根据内存计算的  32位 1GB 64位 32GB

    堆是需要重点关注的一块区域,因为涉及到内存的分配(new关键字,反射等)与回收(回收算法,收集  器等)几乎所有的对象都在堆中分配

9,JVM各版本内存区域的变化

  运行时常量池

    Class文件中的常量池(编译器生成的各种字面量和符号引用)会在类加载后被放入这个区域

    符号引用:

    字面量:String a="aaa"

  JDK1.6

    运行时常量池在方法去中

  JDK1.7

    运行时常量池在堆中

  JDK1.8

    去永久代,使用元空间(空间带线啊哦只受制于机器的内存)替代永久代

    永久代参数 -XX:PermSize;-XX:MaxPermSize =100M 超过100M OOM()

     元空间参数 -XX:MetaspaceSize; -XX:MaxMetaspaceSize

  

  why?

    永久代来存储类信息、常量、静态变量等数据不是个好主意, 很容易遇到内存溢出的问题。 对永久代进行调优是很困难的,同时将元空间与堆的垃圾回收进行了隔离,避免永久代引发的Full GC和OOM等问题;

  在反射和动态代理,会大量产生永久带

  元空间,是根据电脑内存相关

10.直接内存

    不是虚拟机运行时数据区的一部分,也不是java虚拟机规范中定义的内存区域;

       1.如果使用了NIO,这块区域会被频繁使用,在java堆内可以用directByteBuffer对象直接引用并操作;

       2.这块内存不受java堆大小限制,但受本机总内存的限制,可以通过MaxDirectMemorySize来设置(默认与堆内存最大值一样),所以也会出现OOM异常;

       3.避免了在Java 堆和Native 堆中来回复制数据,能够提高效率

 

 

 

     什么时候要有 直接内存?

    可以增加读取速度

    例如kafka,为什么小设置小一点,留一点给本地内存

    设置直接内存,默认和堆大小一样

 

 

功能

  1. 以栈帧的方式存储方法调用的过程,并存储方法调用过程中基本数据类型的变量(int、short、long、byte、float、double、boolean、char等)以及对象的引用变量,其内存分配在栈上,变量出了作用域就会自动释放;(stackoverflow,OOM)

  2.而堆内存用来存储Java中的对象。无论是成员变量,局部变量,还是类变量,它们指向的对象都存储在堆内存中;

线程独享还是共享

  1.栈内存归属于单个线程,每个线程都会有一个栈内存,其存储的变量只能在其所属线程中可见,即栈内存可以理解成线程的私有内存。 堆内存中的对象对所有线程可见。

  2.堆内存中的对象可以被所有线程访问。

空间大小

  1.栈的内存要远远小于堆内存,栈的深度是有限制的,可能发生StackOverFlowError问题。

    

转载于:https://www.cnblogs.com/wanfeng-huabi/p/11581721.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值