概述
java的内存管理采用自动内存管理机制,这样就不需要程序员去写释放内存的代码,而且不容易出现内存泄漏问题。正是由于内存的申请和释放都交给了Java虚拟机,一旦出现内存泄漏和溢出问题时,在不了解Java虚拟机内存结构和自动管理机制的情况下,很难排查问题的所在。所以一个成熟的程序员和架构师,必须很好的掌握Java虚拟机的自动内存管理机制。
运行时数据区
上图的虚拟机运行时数据区是Java虚拟机规范所规定的区域,不同的虚拟机有不同的实现。
程序计数器
程序计数器记录当前线程所执行的Java字节码的地址。当执行的是Native方法时,程序计数器为空。程序计数器是JVM规范中唯一一个没有规定会导致OOM(OutOfMemory)的区域。
Java虚拟机栈
Java虚拟机栈是Java方法执行的内存模型,每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。栈帧(Stack Frame)存储局部变量表,操作数栈,动态链接,方法出口等信息。会抛出StackOverflowError和OOM异常。
本地方法栈
本地方法栈和虚拟机栈非常相似,不同的是虚拟机栈服务的是Java方法,而本地方法栈服务的是Native方法。HotSpot虚拟机直接把本地方法栈和虚拟机栈合二为一。会抛出StackOverflowError和OOM异常。
Java堆
Java堆用于存放对象实例:The heap is the runtime data area from which momory which memory for all class instances and
arrays is allocated。是垃圾收集器管理的主要区域。可细分为:新生代和老年代;新生代又可分为Eden,from Survivor,to Survivor。会抛出StackOverflowError异常。
方法区
方法区存储虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。HotSpot中也成为永久代(Permanent
Generation),(存储的是除了Java应用程序创建的对象之外,HotSpot虚拟机创建和使用的对象)。永久代中的对象并不是永久的,只是历史上被叫做永久代罢了。
方法区在不同虚拟机中有不同的实现,HotSpot在1.7版本以前和1.7版本,1.7后都有变化。
jdk7版本以前的实现
jdk7版本的改动是把字符串常量池移到了堆中。
jdk8 MetaSpace
jdk1.8中则把永久代给完全删除了,取而代之的是
MetaSpace
运行时常量池和静态变量都存储到了堆中,MetaSpace存储类的元数据,MetaSpace直接申请在本地内存中(Native
memory),这样类的元数据分配只受本地内存大小的限制,OOM问题就不存在了。除此之外,还有其他很多好处:
- Take advantage of Java Language Specification property : Classes and associated metadata lifetimes match class loader’s
- Linear allocation only
- No individual reclamation (except for RedefineClasses and class loading failure)
- No GC scan or compaction
- No relocation for metaspace objects
对象的内存布局
Mark Word用于存储对象自身的运行时数据,如哈希码,GC分代年龄,锁状态标志,线程持有的锁,偏向线程ID,偏向时间戳等。
类型指针即对象指向它的类元数据的指针。并不是所有的虚拟机实现都必须在对象数据上保留类型指针(用句柄实现)。
实例数据 存储程序代码中定义的各种类型的字段内容,这部分的存储顺序会受到虚拟机分配策略参数(FieldsAllocationStyle)和字段在Java源码中定义的顺序的影响。HotSpot虚拟机默认的分配策略为longs/doubles,ints,shorts/chars,bytes/booleans,oop(Ordinary
Object Pointers)。
对齐填充 并不是必然存在的,没用特别的含义。HotSpot的自动内存管理系统要求对象的起始地址必须是8字节的整数倍(对象的大小必须是8字节的整数倍)。
对象的创建
虚拟机遇到一条new指令时,首先检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并检查符号引用代表的类是否已被加载,解析和初始化过。如果没有就先执行类的加载过程。接下来虚拟机为新对象分配内存(指针碰撞或空闲列表,Serial,ParNew等带Compact过程的收集器时采用指针碰撞,CMS这种基于Mark-Sweep缩放的收集器时通常采用空闲列表)。
处理并发是通过CAS配上失败重试的方式或者每个线程在堆上预先分配本地线程分配缓冲(Thread Local Allocation Buffer,TLAB)。
内存分配完成后,虚拟机将内存空间都初始化为零值(不包括对象头)。然后对对象头数据进行设置。
在完成以上工作后,从虚拟机的视角来看,一个新的对象已经产生。但从Java程序的视角来看,在执行完new指令之后会接着执行<init>方法,把对象按照程序员的意愿进行初始化,这样一个真正可用的对象才算完全产生出来。
对象的访问定位
通过句柄访问对象
通过直接指针访问对象
这两种对象的访问方式各有优势,使用句柄来访问的最大好吃就是reference中存储的是稳定的句柄地址,在对象被移动时只会改变句柄中的实例数据指针,而reference本身不需要修改
使用直接指针访问的最大好处就是速度快,它节省了异常指针定位的时间开销,由于对象的访问在Java中非常频繁,因此这类开销积少成多也是一项可观的执行成本。
HotSpot 是通过直接指针访问对象的方式进行对象访问的。
参考文章http://java-latte.blogspot.hk/2014/03/metaspace-in-java-8.html
分享到:
相关推荐
Hotspot遵循Java内存模型(JMM),保证了多线程环境下的数据一致性。源码中可以研究如何实现volatile、synchronized以及原子操作的底层细节。 6. **编译器基础设施** 源码揭示了编译器的基础设施,如代码生成器、...
### JDK虚拟机内存模型概述 JVM(Java Virtual Machine)的内存模型主要分为几个区域:堆内存、方法区、程序计数器、虚拟机栈以及本地方法栈。其中,堆内存和方法区是被多个线程共享的,而程序计数器、虚拟机栈和...
HotSpot虚拟机内存模型包括堆内存、栈内存、方法区(JDK8后被元空间取代)、程序计数器和本地方法栈等几大部分。理解这些区域的作用和交互,对于排查内存溢出、理解垃圾收集等工作至关重要。 三、垃圾收集器 JDK8u...
Hotspot实现了Java内存模型(JMM),确保了多线程环境下的数据一致性。它定义了变量访问规则、线程交互规则以及内存可见性,确保了并发编程的正确性。 5. **类加载机制** Hotspot遵循双亲委托模型进行类加载,从...
3. **内存模型(Memory Model)**:HotSpot虚拟机实现了Java内存模型,确保多线程环境下数据的一致性和可见性。 4. **类加载机制(Class Loading)**:HotSpot虚拟机负责加载、验证、准备、解析和初始化类。这部分...
HotSpot源码的分析有助于我们理解JVM的内存模型、垃圾收集机制、类加载过程以及优化策略。在HotSpot中,关键组件如解释器、即时编译器(C1和C2)和运行时系统都有C++实现,这些源码提供了对JVM内部运作的深度洞察。 ...
【JDK 1.8 的 JVM 内存模型】 JVM(Java Virtual Machine)内存模型是Java程序运行的基础,对于实习生来说,理解JVM的工作原理是面试中的常见考点。JDK 1.8的内存模型主要由以下几个部分组成: 1. **程序计数器**...
8. **性能优化**:JDK 1.8在很多方面都进行了性能优化,例如改进的HotSpot虚拟机,它可以动态地优化代码,提高运行效率。 9. **内存管理**:JDK 1.8的垃圾收集器进行了重大改进,如G1垃圾收集器的引入,它能有效地...
通过阅读C++源码,我们可以了解到Java内存模型的工作原理,比如如何执行对象的创建和销毁,以及如何实现高效的并发机制。 HotSpot虚拟机是Oracle JDK中的默认虚拟机,它以其高性能和优秀的优化能力著称。HotSpot的...
1. JVM架构:理解JVM的内存模型、类加载机制、垃圾收集、线程调度等基础概念。 2. 字节码与编译器:研究JVM如何执行字节码,以及如何通过C1和C2编译器进行即时编译优化。 3. 类库实现:深入源码,探索ArrayList、...
4. **内存模型(Memory Model)**:Java 内存模型定义了线程之间如何共享和访问数据,包括堆内存、栈内存和方法区(在Java 8及以后的版本中称为元空间)。 5. **字符串常量池(String Pool)**:在 OpenJDK 8 中,...
《JVM内存模型详解》 Java虚拟机(JVM)内存模型是理解Java应用程序性能和内存使用的关键。本文将深入探讨HotSpot虚拟机中的内存结构,主要包括对象的创建、内存布局以及运行时数据区的各个部分。 首先,我们来看...
5. **内存模型**:HotSpot虚拟机内存分为堆(Heap)、栈(Stack)、方法区(Method Area)和本地方法栈(Native Method Stack)等区域,书中会解释各部分的作用,以及如何调整内存参数以优化性能。 6. **性能监控和...
1. **JVM**: Java虚拟机是Java程序运行的基础,其关键部分如字节码解释器、垃圾收集器、内存管理等都在`src/hotspot`目录下。通过阅读这部分源码,我们可以了解JVM如何执行字节码、如何管理内存以及优化技术如即时...
JDK 7增加了对Fork/Join框架的支持,这是一种用于并行任务处理的新模型。通过将大的计算任务拆分成多个小任务来并行执行,可以极大地提高程序的运行效率,特别是在多核处理器环境中。 ##### 2.4 安全性改进 JDK 7...
JDK 1.6引入了更轻量级的内存模型,即JSR 133,它规定了在并发环境下,如何正确地访问和修改共享变量,保证了线程间的可见性,避免数据一致性问题。 ### 5. 更好的垃圾收集 JDK 1.6对垃圾收集器进行了优化,提供了...
关于String.intern()方法,这个问题都被问烂了,有的文章在分析的时候还在用jdk1.7,jdk1.8之后内存模型发生了变化,内存的变化也会影响intern方法的执行,这里有必要写文章分析一下,请大家务必从头开始看,这样...
Hotspot JVM,全称Hotspot Virtual Machine,是Java开发工具包(JDK)中的关键组成部分,负责运行Java应用程序。它由Oracle公司开发,以其出色的性能优化和动态编译能力而闻名。Hotspot VM的名字来源于其核心理念...
- **编译优化**:JDK1.7的HotSpot虚拟机在JIT(Just-In-Time)编译方面有了进一步的提升,能够更快地识别和优化热点代码。 - **内存管理**:对垃圾回收算法进行了优化,降低了GC停顿时间,提高了系统响应速度。 4...
6. **内存管理**:JDK1.6改进了垃圾收集机制,提升了内存管理效率,减少了程序暂停时间。 7. **NIO.2(New I/O 2)**:引入了更现代的文件I/O API,提供了异步I/O操作和文件系统感知的功能。 8. **Swing和AWT组件*...