Notes
  • Introduce
  • Go
    • Grammar
      • Basic
      • Goroutines & Channels
      • Test
    • System Library
      • Module
      • sync
      • context
      • net
    • Concurrency in Go
    • The Go Memory Model
    • Code Snippet
  • Rust
    • The Rust Programming Language
    • Rust by Example
  • JAVA
    • Preface
    • Grammar
      • Basic
      • Data Types
      • Operator
      • Exceptions
    • Class Libraries
      • Collection
      • Stream
      • IO
      • NIO
      • RMI
    • Concurrency
      • Preface
      • JMM
      • Synchronized & CAS
      • Deadlock
      • Thread
      • Lock & Condition
      • Utility Class
      • Thread-safe Collection
      • Atomic Class
      • Fork/Join
      • Concurrency Design Patterns
        • Immutable
        • Copy-on-Write
        • ThreadLocal
        • Multitheading If
        • Division
    • JVM
      • Class & Instance Initialization
      • Runtime Data Area
      • Garbage Collection
    • Web Container
      • Tomcat Architecture
      • Jetty Architecture
    • Spring
    • Tuning
      • Programming
  • Computer Science
    • Computer Organization
    • Algorithm
      • Complexity
      • Linear List
      • Sort
      • Binary Search
      • Skip List
      • Hash Table
      • Tree
      • Graph
      • String Matching
      • Bloom Filter
      • Greedy Algorithm
      • Divide and Conquer
      • Back Tracking
      • Dynamic Programming
    • Network Protocol
      • Pysical Layer
      • Data Link Layer
      • Network Layer
      • Transport Layer
      • Application layer
      • HTTP
      • HTTP/2 in Action
    • Operating System
      • Basic
      • System Initialization
      • Diagnostic Tools
      • CPU Diagnosis
      • Memory Diagnosis
      • Disk Diagnosis
      • Network Diagnosis
      • Monitor System
    • Design Patterns
      • UML
      • OOP
      • Principle
      • Refactoring & Specification
      • Creational
        • Singleton
        • Factory
        • Builder
        • Prototype
      • Structural
        • Proxy
        • Bridge
        • Decorator
        • Adapter
        • Facade
        • Composite
        • FlyWeight
      • Behavioral
        • Observer
        • Template Method
        • Strategy
        • State
        • Iterator
        • Chain of Responsibility
    • Distributed System
      • Protocol & Algorithm
      • Transcation
      • Theory
      • Resource Management
      • Scheduling
      • Computing
      • Message Queue
      • Cache
      • Consistent Hashing
  • database
    • InfluxDB
      • In-Memory Index
      • Meta
    • MySQL
      • SQL
      • Architecture
      • Log
      • Transaction
      • Indexing
      • Lock
      • Storage
    • Redis
    • Elasticsearch
      • Local Debug
    • HBase
    • Kafka
    • ZooKeeper
  • Reading
    • RocketMQ
    • 演说之禅
    • So Good They Can't Ignore You
    • 学会提问
    • Lecture
  • Other
    • v2ray
    • Kubernetes
    • Git
    • Maven
    • Anaconda And Conda
    • Fuck! Shit!
      • Remove Final by Reflection
      • Ingress Host
      • ExecuterService submit
  • Open source contribution
Powered by GitBook
On this page
  • Java堆
  • 方法区
  • Java虚拟机栈
  • 本地方法栈
  • 程序计数器
  • 直接内存

Was this helpful?

  1. JAVA
  2. JVM

Runtime Data Area

PreviousClass & Instance InitializationNextGarbage Collection

Last updated 6 years ago

Was this helpful?

JVM = 类加载器(ClassLoader) + 执行引擎(Execution engine) + 运行时数据区域(Runtime data area) 。如下图所示:

Runtime data area:Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的区域。如下图是运行时数据区域的详细结构:

Java堆

  • Java堆(Java heap)是线程公有。

  • 原则上所有的对象实例都存在堆上,但是JIT与逃逸分析技术等除外。是垃圾收集器管理的主要区域。

  • 一般来说,Java堆(Java heap)是内存中最大的一块。

  • 虚拟机规范规定,Java堆可以处于物理上不连续的内存空间。

  • 会抛出OutOfMemoryError异常。

从内存回收的角度来看,由于收集器一般采用分代收集的特点,所以堆一般可以细分为不同的区域。新生代(Eden空间、From Survivor空间、To Survivor空间等)和老年代等。

方法区

  • 方法区(Method area)也是线程公有。

  • 用于存放已被加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

  • 虚拟机规范把方法区描述为堆的一个逻辑部分

  • 不需要连续的内存空间。

  • 会抛出OutOfMemoryError异常。

很多人把方法区称为永久代(Permanent Generation),本质上是不对的。只是因为HotSpot在1.7之前用永久代来实现方法区,但是对于其它虚拟机(JRockit等)并不存在永久代的概念。

永久代与元空间

  • JDK1.7之前,HotSpot 使用永久代实现方法区。

  • JDK1.7 ,HotSpot 中符号引用(Symbols)被移动到 Native Heap中,字面量(interned strings)转移到了java heap;类的静态变量(class statics)转移到了java heap(移动到了java.lang.Class对象中)。

  • 在 JDK1.8 中,永久代已完全被元空间(Meatspace)所取代。元空间的本质和永久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代之间有两个区别:

    • 存储位置:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制。​

    • 存储内容:元空间存储类的元信息,静态变量和常量池等并入堆中。也就是说永久代的数据被分到了堆和元空间。

  • PermSize和MaxPermSize参数已移除。

  • 元空间常用的参数:

    1. MetaspaceSize:初始化的Metaspace大小,控制元空间发生GC的阈值。GC后,动态增加或降低MetaspaceSize。

    2. MaxMetaspaceSize:限制Metaspace增长的上限。

    3. MinMetaspaceFreeRatio:当进行过Metaspace GC之后,会计算当前Metaspace的空闲空间比,如果空闲比小于这个参数(即实际非空闲占比过大,内存不够用),那么虚拟机将增长Metaspace的大小。默认值为40,也就是40%。

    4. MaxMetasaceFreeRatio:当进行过Metaspace GC之后, 会计算当前Metaspace的空闲空间比,如果空闲比大于这个参数,那么虚拟机会释放Metaspace的部分空间。默认值为70,也就是70%。

Java虚拟机栈

  • Java虚拟机栈(VM stack)是线程私有。

  • 生命周期与线程相同。

  • 虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

  • 局部变量表存放了编译期可知的8种基本数据类型、对象引用和returnAddress类型(指向了一条字节码指令的地址)。局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的。

  • 会抛出StackOverflowError(栈深度大于虚拟机所允许的深度)和OutOfMemoryError(无法申请到足够的内存)异常。

注意区分栈帧和栈这两个概念。 栈指的是整个线程的执行栈, 栈帧是栈中的一个单位, 每个方法对应一个栈帧。 JVM会对Java栈执行两种操作: 压栈和出栈。 这两种操作在执行时都是以帧(栈帧)为单位的。 当调用了一个新的方法, 就会压入一个栈帧, 当一个方法调用完成, 就会弹出这个方法的栈帧, 回到调用者的栈帧。

本地方法栈

  • 本地方法栈(Native method stack)是线程私有。

  • 与Java虚拟机栈类似,虚拟机栈执行Java方法,本地方法栈执行Native方法。

  • 会抛出StackOverflowError和OutOfMemoryError异常。

程序计数器

  • 程序计数器(Program Counter )是线程私有。

  • 可以看做是当前线程所执行的字节码的行号指示器。

  • Java会有线程切换,正是这个计数器来保证线程切换回来后能够恢复到正确的执行位置。

  • 如果这个线程执行的是Java方法,则计数器的值为正在执行的字节码指令的地址;如果是Native方式,则这个计数器值则为空(Undefined)。

  • 唯一不会抛出OutOfMemoryError异常。

直接内存

  • 直接内存(Direct Memory)并不是虚拟机运行时区域的一部分,也不是虚拟机规范中定义的内存区域。

  • NIO可以直接分配堆外内存,可以不用在本地方法栈和虚拟机栈中复制数据,通过一个存储在 Java 堆里的 DirectByteBuffer 对象作为这块内存的引用进行操作。

  • 也可能导致OutOfMemoryError。

JDK8永久代变化