美文网首页
JVM(一)java内存区域

JVM(一)java内存区域

作者: 7ColorLotus | 来源:发表于2020-05-28 23:35 被阅读0次
  • Sun/Oracle系列的虚拟机

    1. Sun Classic/Exact VM 第一款商用JAVA虚拟机
    2. HotSpot VM 目前使用范围最广的JAVA虚拟机
    3. Mobile系列 面对移动和嵌入式市场
  • 其他公司的虚拟机

    1. BEA JRockit
    2. IBM J9 VM
    3. BEA Liquid VM
    4. Google Android Dalvik VM
    5. Apache Harmony
    6. Microsoft JVM及其他
  • 未来的的JAVA技术

    1. 模块化
    2. 混合语言
    3. 多核并行
    4. 丰富语法
    5. 64位
    6. 更强的垃圾回收
  • 运行时数据区域

    1. 定义:java虚拟机在执行java程序的过程中会把它所管理的内存划分为若干个不同的数据区域

    2. 类型:
      1> 程序计数器:较小的内存空间,当前线程执行的字节码的行号指示器;各个线程之间独立存储,互不影响
      2> 虚拟机栈:线程私有,生命周期和线程,每个方法在执行的同事都会创建一个栈帧用于存储局部变量表,操作数栈,动态链接,方法出口等信息。方法的执行就对应着栈帧在虚拟机栈中入栈和出栈的过程;栈里面存放着各种基本数据类型和对象的应用(-XSS),默认大小1M
      3> 本地方法栈:本地方法栈保存的是navtive方法的信息,当一个JVM创建的线程调用native方法后,JVM不再为其在虚拟机栈中创建栈帧,JVM只是简单地动态链接并直接调用native方法
      4> java堆:java堆是javaver需要重点关注的一块区域,因为涉及到内存的分配(new关键字,反射等)与回收(回收算法,收集器等)

         a, -Xms 堆的最小值
         b, -Xmx 堆的最大值
         c, -Xmn 新生代的大小
         d, -XX:NewSize 新生代最小值
         e, -XX:MaxNewSize 新生代最大值
      

      5> 方法区(jdk7以后不存在了):也叫永久区,用于存储已经被虚拟机加载的类信息,常量("zsd","123"等),静态变量(static变量)等数据

         a, -XX:PermSize(jdk7及以前)
         b, -XX:MaxPermSize(jdk7及以前)
         c, -XX:MetaspaceSize(jdk7以后)
         d, -XX:MaxMetaspaceSize(jdk7以后)
      

      6> 运行时常量池:运行时常量池是方法区的一部分,用于存放编译期生成的各种字面量("zsd","123"等)和符号引用。jdk7后放在堆里,jdk7即以前放在方法区里

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

      7> 直接内存:不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域;网络推送使用最多

         a, 如果使用NIO,这块区域会被频繁使用,在java堆内可以用directByteBuffer对象直接引用并操作
         b, 这块内存不受java堆大小限制,但受本机总内存的限制,可以通过MaxDirectMemorySize来设置(默认与堆内存最大值一样),所以也会出现OOM异常
      
    3. JDK1.6内存区域


      JDK1.6内存区域.png
    4. JDK1.7内存区域


      JDK1.7内存区域.png
  • 站在线程角度来看java内存区域

    1. 线程共享内存区:java堆,方法区
    2. 线程私有内存区:虚拟机栈,本地方法栈,程序计数器。随着线程产生和消亡,因此不需要过多考虑内存回收的问题。编译时确定所需内存大小
  • 深入辨析堆和栈

    1. 功能
      1> 以栈帧的方式存储方法调用的过程,并存储方法调用过程中基本数据类型的变量(Int,short,long,byte,float,double,boolean,char等)以及对象的引用变量,其内存分配在栈上,变量出了作用域就会自动释放;
      2> 而堆内存用来存储Java中的对象。无论是成员变量,还是类变量,他们指向的对象都存储在堆内存中

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

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

  • 方法的出入栈

    1. 方法会打包成栈帧,一个栈帧至少要包含局部变量表,操作数栈和帧数据区
    2. 栈上分配
      1> 跟着函数调用自行销毁,提高性能
      2> 逃逸分析 : 判断方法内的变量是否会逃出函数体
      3>栈上分配演示
      a, -server: JVM运行的模式,才能进行逃逸分析 。其他选项:mix/client
      b, -Xmx 10m: 堆的大小
      c, -XX:+DoEscapeAnalysisi:启用逃逸分析。"+"开启功能,"-"关闭功能
      d, -XX:+PrintGC:打印GC日志
      e, -XX:+EliminateAllocations:标量替换。变成"-"就不是栈上分配
      f, -XX:-UseTLAB:TLAB(ThreadLocalAllocBuffer)事先为每个线程分配一块私有内存
  • 虚拟机中的对象的初始化过程

    1. 检查加载
    2. 分配内存
      1> 划分内存:指针碰撞和空闲列表
      2> 并发安全问题:用CAS配上失败重试本地线程分配缓冲
    3. 内存空间初始化
    4. 设置
    5. 对象初始化
  • 对象的内存布局

    1. 对象头:对象自身的运行数据(hashCode等)和类型指针
    2. 实例数据:程序代码中所定义的各种类型的字段内容
    3. 对齐填充:虚拟机处理,占位,对象的大小必须是8个字节整数倍
  • 对象的访问定位

    1. 使用句柄:指向句柄(类似指示牌)池

    2. 直接指针:hotspot虚拟机使用的访问方式

    3. 示例图

      对象访问定位.png
  • 堆参数设置,对性能的影响和内存溢出实战

    1. java堆溢出
      1> java.lang.OutOfMemoryError: Java heap space 在分配的时候,有巨型对象在分配
      2> java.lang.OutOfMemoryError: GC overhead limit exceeded 某个循环里不停的分配对象,但是分配太多,把堆撑爆了
    2. 新生代配置
      1> -XX:NewSize/MaxNewSize 优先级最高
      2> -Xmn (NewSize=MaxNewSize) 优先级第二
      3> -XX:NewRatio 新生代和老年代的比例 优先级最小
      4> -XX:SurvivorRatio 表示eden和Surviror的比值,缺省为8 Eden:FromS:ToS = 8:1:1
      5> 示例 生成10M
      -Xms20M -Xmx20M -XX:+PrintGCDetails -Xmn2m -XX:SurvivorRatio=2
      -Xms20M -Xmx20M -XX:+PrintGCDetails -Xmn7m -XX:SurvivorRatio=2
      -Xms20M -Xmx20M -XX:+PrintGCDetails -Xmn15m -XX:SurvivorRatio=8
      -Xms20M -Xmx20M -XX:+PrintGCDetails -XX:NewRatio=2 新生代和老年代比例 1:2
    3. 方法区和运行时常量池溢出
    4. 虚拟机栈和本地方法栈溢出
      1> java.lang.StackOverFlowError 要考虑是否有无限递归
    5. 本机直接内存溢出
      1> ByteBuffer b = ByteBuffer.allocateDirect(size)

相关文章

  • Java内存区域与内存溢出异常

    JVM——Java内存区域 链接:Java内存区域[https://segmentfault.com/a/1190...

  • 8. JVM Memory Model and Visibili

    前言:JVM内存模型、Java内存区域、GC分代回收容易搞混。前面讲解了JVM内存区域,它是Java代码编译成.c...

  • JVM系列-JVM内存区域与GC机制

    JVM内存区域 了解Java GC之前,必须先搞清楚JVM中内存区域的划分。 JVM中内存区域大致可分为如上图所示...

  • JVM内存区域与内存溢出

    Java程序是交由JVM执行的,所以我们在谈Java内存区域划分的时候事实上是指JVM内存区域划分。在讨论JVM内...

  • Java内存区域与内存溢出异常

    Java内存区域与内存溢出异常 @(Java虚拟机)[jvm, 内存] [TOC] 运行时数据区域 Java虚拟机...

  • JVM从入门到精通系列(二):JVM内存区域及运行时内存

    JVM内存区域 JVM 内存区域主要分为线程私有区域【程序计数器、虚拟机栈、本地方法区】、线程共享区域【JAVA ...

  • JAVA运行时内存及垃圾回收

    JAVA 1. Java运行时内存区域 在JAVA运行时的内存区域中,由JVM管理的内存区域分为以下几个模块: 程...

  • JVM内存区域划分

    一、概述 根据《Java虚拟机规范》的描述,JVM所管理的内存区域如下图所示: JVM内存区域主要分为线程私有区域...

  • JVM内存模型

    JVM内存区域 JVM内存区域主要分为线程私有区域【程序计数器,虚拟机栈,本地方法栈】,线程共享区域【JAVA堆,...

  • JMM与可见性

    JMM jvm运行时数据区域 Java 内存区域和内存模型是不一样的东西,内存区域是指 Jvm 运行时将数据分区域...

网友评论

      本文标题:JVM(一)java内存区域

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