深入理解java虚拟机
- 格式:docx
- 大小:799.59 KB
- 文档页数:20
深入分析JVM的优点与缺点JVM(Java虚拟机)是一种在计算机上运行Java字节码的虚拟机,它具有许多优点和一些缺点。
本文将深入分析JVM的优势和不足之处,具体如下:优点:1. 跨平台性:JVM是为Java程序设计语言而创建的虚拟机,可以在不同的操作系统上运行Java程序,无需重新编写或修改代码。
这种跨平台性使得Java成为一种非常流行的编程语言。
2.内存管理:JVM提供了自动内存管理,通过垃圾回收器自动处理内存分配和释放,这样程序员就不需要手动管理内存,减轻了开发人员的负担并且避免了常见的内存泄漏和溢出问题。
3.安全性:通过安全沙箱机制,JVM可以在程序执行期间限制程序对底层系统资源的访问。
这样可以防止恶意软件和病毒对计算机的破坏,提高了安全性。
4. 高可移植性:由于JVM的跨平台性,Java程序一旦在一个平台上编写和测试完成,就可以在其他平台上运行,无需重新编写和调试代码。
5. 高性能:尽管Java是解释型语言,但JVM使用即时编译器(JIT)将Java字节码直接编译成机器码,从而提高了程序的执行效率。
JIT编译器可以对热点代码进行优化,提供接近于本地代码执行的性能。
不足之处:1.内存消耗:JVM启动和运行需要占用较大的内存,而且由于垃圾回收机制,JVM的内存占用也较高。
在一些资源有限的环境中,这可能导致问题。
2. 执行速度:虽然JIT编译器可以提高Java程序的执行速度,但与本地代码相比,Java程序的执行速度仍然较慢。
这一点在对实时性要求较高的应用程序中可能会成为问题。
3.配置复杂性:由于JVM的各种配置选项和优化参数较多,使得调优和优化JVM变得复杂。
不正确的配置可能导致性能下降或其他问题。
4.学习成本:相对于其他编程语言和平台,学习和理解JVM的工作原理和内部机制可能需要更多的时间和精力。
5. 移植性限制:尽管JVM使得Java程序具有高度可移植性,但一些情况下,特定平台的限制或特性可能会对Java程序的移植性产生一些限制。
介绍jvm的书-回复
以下是一些关于Java虚拟机(JVM)的书籍推荐:
1.《深入理解Java虚拟机:JVM高级特性与最佳实践》(作者:周志明)这本书详细介绍了JVM的工作原理和性能优化方法,适合对JVM有一定了解并希望深入了解的读者。
2.《Java虚拟机规范》(作者:Oracle公司)
这是官方发布的JVM规范文档,详细描述了JVM的实现细节和标准规定,适合需要深入研究JVM内部机制的读者。
3.《Java并发编程实战》(作者:Brian Goetz等)
虽然不是专门介绍JVM的书,但是书中讨论了很多与JVM相关的并发编程问题,并提供了很多实用的解决方案。
4.《Effective Java》(作者:Joshua Bloch)
这也是一本非专门介绍JVM的书,但是其中包含了大量关于如何编写高效、可维护的Java代码的建议,这些建议对于理解和使用JVM都非常有帮助。
java虚拟机的工作原理Java虚拟机(JVM)是Java程序运行的环境,它负责解释和执行Java字节码。
JVM的工作原理可以分为三个主要的部分:类加载、字节码执行和垃圾回收。
1.类加载:JVM通过类加载器将Java字节码加载到内存中。
类加载器根据类路径在文件系统或网络中查找并读取字节码文件,然后将其转化为JVM运行时数据结构,如类和方法的元数据。
加载完成后,JVM会在方法区中存储类的元数据,并在堆中分配内存来存储类的实例。
2.字节码执行:3.垃圾回收:JVM提供垃圾回收机制来自动释放不再使用的内存。
JVM会跟踪每个对象的引用,当一个对象没有引用时,即被视为垃圾。
垃圾回收器定期执行垃圾收集操作,释放垃圾对象占用的内存。
垃圾回收器有不同的实现策略,如标记-清除、引用计数、复制、标记-整理等。
除了以上三个主要的部分,JVM还包含其他组件,如堆内存、栈、方法区等。
堆内存用于存储对象实例,栈用于存储局部变量和方法调用参数,方法区用于存储类的元数据和静态数据。
JVM的工作过程如下:1. 通过类加载器加载Java字节码。
2.解释执行或JIT编译字节码。
3.根据需要进行垃圾回收和内存管理。
4.执行程序。
JVM的优点是跨平台性、自动内存管理和高性能。
通过JVM,Java程序可以在不同的硬件和操作系统上运行,无需修改源代码。
JVM的自动内存管理功能减轻了开发人员对内存管理的负担,避免了内存泄漏和越界访问等错误。
JVM的即时编译技术能够将热点代码优化为本地机器代码,提高程序的执行效率。
在实际的Java应用开发中,了解JVM的工作原理有助于编写高效的代码和解决性能问题。
开发人员可以通过调整JVM参数、选择合适的垃圾回收器和内存分配策略来优化程序的性能。
同时,了解JVM的工作原理还有助于理解虚拟机层面的问题和调优技巧,提升应用的可靠性和稳定性。
JVM 原理解释JVM 全称是 Java Virtual Machine ,Java 虚拟机,这个 JVM 你是看不到的,它存在内存中。
我们知道计算机的基本构成是:运算器、控制器、存储器、输入和输出设备,那这个 JVM 也是有这成套的元素,运算器是当然是交给硬件 CPU 还处理了,只是为了适应“一次编译,随处运行”的情况,需要做一个翻译动作,于是就用了JVM 自己的命令集,JVM 的命令集则是可以到处运行的,因为 JVM 做了翻译,根据不同的CPU ,翻译成不同的机器语言。
JVM 是一个内存中的虚拟机,那它的存储就是内存了,我们写的所有类、常量、变量、方法都在内存中。
JVM 的组成部分Class Loader 类加载器类加载器的作用是加载类文件(.class)到内存,Class Loader 加载的 class 文件是有格式要求的。
类加载的最终产品是位于运行时数据区的堆区的Class对象。
Class对象封装了类在方法区内部的数据结构。
并且向JAVA程序提供了访问类在方法区内的数据结构。
JVM加载class文件的原理机制1. Java 中的所有类,必须被装载到 JMV 中才能运行,这个装载工作是由 JVM 中的类装载器完成的,类装载器所做的工作实质是把类文件从硬盘读取到内存中。
2. Java中的类大致分为三种:a) 系统类b) 扩展类c) 由程序员自定义的类3. 类装载方式,有两种:a) 隐式装载,程序在运行过程中当碰到通过 new 等方式生成对象时,隐式调用类装载器加载对应的类到jvm中。
b) 显式装载,通过 class.forname() 等方法,显式加载需要的类。
4. 类加载的动态性体现一个应用程序总是由n多个类组成,Java 程序启动时,并不是一次把所有的类全部加载后再运行,它总是先把保证程序运行的基础类一次性加载到 JVM 中,其它类等到 JVM 用到的时候再加载,这样的好处是节省了内存的开销。
unrecognized vm option permsize -回复题目:深入理解Java虚拟机中的“unrecognized vm option permsize”引言:在Java开发过程中,可以通过在`java`命令后添加不同的虚拟机参数对程序的运行进行调优。
然而,有时候在执行Java程序时,可能会遇到“unrecognized vm option permsize”这样的错误提示。
本文将一步一步地解释这个错误提示的原因,并进一步了解Java虚拟机中的`permsize` 参数。
第一步:理解`permsize` 参数在探索这个问题之前,让我们先了解一下`permsize` 参数。
在Java虚拟机中,`permsize` 参数被用于设置持久代(Permanent Generation)的初始大小。
持久代是Java虚拟机的一部分,它用于存储Java类的元数据、字符串常量以及其他在运行时不会被垃圾回收器回收的数据。
在Java 8之前的版本中,`permsize` 参数被用来设置持久代的初始大小。
第二步:寻找错误提示的原因当我们在运行Java程序时,如果我们使用的是Java 8或更高版本的话,可能会收到`unrecognized vm option permsize`的错误提示。
为了理解这个错误,我们需要查看JDK版本中的更改。
第三步:检查JDK版本在Java 8中,持久代被元空间(Metaspace)所取代。
元空间使用本地内存而不是Java堆来存储类的元数据。
由于这个更改,`permsize` 参数在Java 8及更高版本中已经被弃用。
为了解决这个错误,我们需要检查JDK版本并相应地调整虚拟机参数。
第四步:调整虚拟机参数如果我们使用的是Java 8或更高版本,应该使用`metaspaceSize` 参数来调整元空间的大小。
我们可以在`java`命令后面添加`-XX:MetaspaceSize` 参数来设置元空间的初始大小。
java底层原理书籍
以下是一些关于Java底层原理的书籍推荐(不包含标题):
1. "深入理解Java虚拟机(第二版)" - 周志明
2. "Java多线程编程核心技术" - 周立
3. "Java并发编程实战" - Brian Goetz等
4. "Java性能权威指南" - Charlie Hunt等
5. "深入了解JVM字节码" - 孙博
6. "Java网络编程实战" - 薛宇飞
7. "Java虚拟机规范(Java SE 8版)" - James Gosling等
8. "深入JavaWeb技术内幕" - 李兴华等
9. "揭秘Java虚拟机:JVM设计原理与实现" - 林绍雄
10. "Java性能优化权威指南" - Pierre-Hugues Charbonneau等
这些书籍涵盖了Java底层原理的各个方面,旨在帮助读者深入理解Java虚拟机、多线程编程、性能优化等重要主题。
jvm 的原理JVM(Java Virtual Machine)是一种能够执行Java字节码的虚拟机。
它是Java技术的核心,负责将Java源代码编译为平台无关的字节码,并在不同的操作系统上执行这些字节码。
JVM的原理可以简单概括为以下几个方面:1. 类加载:JVM首先通过类加载器加载Java源代码编译生成的字节码文件。
类加载器将字节码文件加载到JVM中,并解析字节码文件的结构,创建对应的类模板。
2. 内存管理:JVM将内存划分为不同的区域,包括堆、栈、方法区等。
其中,堆是用于存储对象实例的区域,栈用于存储方法的调用栈,方法区则存储类的元数据信息。
JVM通过垃圾回收机制自动管理堆内存,释放不再使用的对象。
3. 即时编译:JVM在执行字节码时,会将热点代码(即频繁执行的代码)通过即时编译器(Just-In-Time Compiler)编译为本地机器码,以提高执行效率。
即时编译器会根据运行时的情况进行优化,如方法内联、循环展开等。
4. 解释执行:对于非热点代码,JVM会使用解释器将字节码逐条解释执行。
解释器将字节码转换为机器码并执行,但执行效率相对较低。
5. 安全机制:JVM提供了安全管理器(Security Manager)来保护系统安全。
安全管理器可以控制JVM对外部资源的访问权限,防止恶意代码对系统造成破坏。
6. 异常处理:JVM提供了异常处理机制来处理程序中的异常情况。
当程序发生异常时,JVM会根据异常处理器(Exception Handler)的配置,选择相应的处理方式,如打印异常信息、捕获并处理异常等。
7. 多线程支持:JVM支持多线程并发执行。
它通过线程调度器(Thread Scheduler)来调度各个线程的执行顺序,实现多线程的并发执行。
8. 跨平台性:由于JVM将字节码作为中间语言,可以在不同的操作系统上执行Java程序。
这使得Java具有较好的跨平台性,只需在不同平台上安装对应的JVM即可。
java的基本概念Java的基本概念Java是一种高级编程语言,由Sun Microsystems于1995年推出,现在已被Oracle收购。
它是一种面向对象编程语言,适用于跨平台应用程序开发,因此广泛应用于Web、移动、桌面等各种领域。
在学习Java 编程之前,需要了解一些基本概念。
一、Java虚拟机(JVM)Java虚拟机是Java的重要组成部分之一,它是一个运行Java字节码的虚拟机,具有独立于硬件平台的特性。
JVM将Java字节码解释为机器指令,使Java程序能在各种操作系统上运行。
JVM还负责Java程序内存的分配和垃圾回收。
Java语言的安全性和可移植性也得益于JVM。
二、面向对象编程(OOP)Java是一种面向对象编程语言。
它的核心思想是将程序看作由对象组成,每个对象都有自己的属性和行为。
OOP的优点在于能够提高代码复用性,使得代码更易于扩展和维护,也有利于开发大型应用程序。
在Java中,所有的数据都是以对象的形式进行处理,常用的面向对象概念包括封装、继承和多态。
三、数据类型Java支持各种数据类型,包括基本数据类型和引用数据类型。
基本数据类型包括8种:byte、short、int、long、float、double、char和boolean,它们分别用于存储不同类型的数据。
引用数据类型包括类、接口、数组等类型。
Java还支持自动装箱和拆箱,即将基本数据类型自动转换为包装类型,方便代码的编写。
四、流程控制Java支持多种流程控制语句,包括顺序结构、选择结构和循环结构。
顺序结构是按照代码的顺序执行,选择结构根据条件选择不同的执行路径,循环结构则是重复执行同一个代码块。
Java还支持异常处理机制,即在程序运行时捕获异常并进行相应的处理,保证程序的健壮性和可靠性。
五、数组数组是Java中常用的数据结构之一。
它是一组固定大小的有序元素集合,可以存储同一类型的数据。
Java的数组可以是一维数组或多维数组,数组的下标从0开始计数。
深入剖析java虚拟机源码剖析与实例详解《深入剖析Java虚拟机源码剖析与实例详解》一书是近年来Java虚拟机领域的一本经典著作。
本文将从四个方面对这本书进行详细的剖析和评价。
一、内容概述本书主要从解读Java虚拟机的本质来讲解Java虚拟机,全书共分八个章节,内容分为虚拟机概述、运行时内存区域、执行引擎、类加载机制、字节码指令集和类文件结构六大块。
作者通过对Java虚拟机的实现原理剖析和对源代码关键代码的解析,帮助Java开发人员和技术爱好者更好地理解Java虚拟机的实现机制。
二、内容分析1. 虚拟机概述本章主要是介绍了Java虚拟机的工作原理、Java虚拟机与JDK、JRE的关系等,也阐述了一些JVM的基本概念和相应的JVM命令,如应用程序、类、对象、内存划分、垃圾回收、线程、栈等。
2. 运行时内存区域本章主要介绍Java虚拟机运行时内存的区域,分为线程共享区、堆、方法区、程序计数器,其中程序计数器是一种较为特殊的内存区域,主要用来记录线程正在执行的字节码指令的地址。
3. 执行引擎本章主要介绍Java虚拟机的执行引擎,执行引擎是JVM最具有特色的功能之一,主要起到将字节码翻译成具体的硬件指令的作用。
4. 类加载机制本章主要介绍Java类加载的机制,从类文件的加载、连接和初始化这三个阶段来解析。
5. 字节码指令集本章主要介绍了Java字节码指令集,这是Java虚拟机实现的关键之一。
字节码指令集是一个指令集,主要用来描述Java程序的行为。
6. 类文件结构本章主要介绍了Java类文件的内部结构,包括常量池、类信息、字段、方法等内容。
这些知识对于理解Java 虚拟机内部的运行机制和机制实现是非常有帮助的。
三、优点分析1. 按照设计和实现原理展开本书以Java虚拟机的设计原理和实现机制为主干,一步步推展,非常有条理和逻辑。
仔细分析每个过程,熟悉JVM的理论知识,加深JVM使用的理解,促进JVM的实际应用。
中级java面试题及答案整理中级Java面试题及答案整理1. 什么是Java虚拟机(JVM)?Java虚拟机(JVM)是一个可以执行Java字节码的虚拟计算机。
它是一个抽象计算机的概念,提供了一种机制,使得Java程序可以在多种平台上运行而不需要重新编译。
2. 解释Java中的多线程。
Java中的多线程允许程序同时执行两个或多个线程。
线程是程序执行的最小单位,每个线程可以独立执行任务。
Java提供了Thread类和Runnable接口来创建和管理线程。
3. 什么是Java集合框架?Java集合框架是一组接口和类,提供了一种存储和处理对象集合的方式。
它包括List、Set和Map等接口,以及ArrayList、LinkedList、HashSet、HashMap等实现类。
4. 如何在Java中实现单例模式?单例模式确保一个类只有一个实例,并提供一个全局访问点。
在Java 中实现单例模式的一种方法是使用私有构造函数和静态变量来存储实例。
5. 什么是Java中的异常处理?异常处理是Java中用于处理程序运行时发生的异常情况的机制。
它包括try、catch、finally和throw关键字,以及自定义异常类。
6. 解释Java中的垃圾回收机制。
垃圾回收是Java内存管理的一个特性,它自动回收不再使用的对象所占用的内存。
Java虚拟机(JVM)有一个垃圾回收器,定期检查内存中的对象,并回收那些不再被引用的对象。
7. 什么是Java反射?Java反射API允许程序在运行时查询和操作类、接口、字段和方法。
它提供了一种动态访问和操作Java对象的方式。
8. 什么是Java注解?注解(Annotations)是Java语言的一个特性,用于在代码中添加元数据。
注解可以用于类、方法、变量等元素上,通常用于编译时或运行时的处理。
9. 什么是Java泛型?泛型是Java 5引入的一个特性,它允许在编译时进行类型检查,从而避免运行时的类型错误。
深入理解java虚拟机(一)虚拟机内存划分Java虚拟机在执行Java程序时,会把它管理的内存划分为若干个不同的数据区。
这些区域有不同的特性,起不同的作用。
它们有各自的创建时间,销毁时间。
有的区域随着进程的启动而创建,随着进程结束而销毁,有的则始终贯穿虚拟机整个生命周期。
Java虚拟机运行时内存区域主要分为七部分,分别是:程序计数器,Java虚拟机栈,本地方法栈,方法区,Java堆,运行时常量池,直接内存。
如上图所示(图片来源于网络):蓝色区域包裹的部分为运行时几个数据区域:白色的部分为线程私有的,既随着线程的启动而创建。
每个线程都拥有各自的一份内存区域。
它们是:JAVA栈(JAVA STACK),本地方法栈(NATIVE METHOD STACK),和程序计数器(PROGRAM COUNTER REGISTER)。
黄色部分是线程共享的,所有的线程共享该区域的内容。
他们是:方法区(METHOD AREA),堆(HEAP)。
我们分别来介绍这些区域。
(1)程序计数器(program counter register)学过计算机组成原理的都知道计算机处理器中的程序计数器。
当处理器执行一条指令时,首先需要根据PC中存放的指令地址,将指令由内存取到指令寄存器中,此过程称为“取指令”。
与此同时,PC中的地址或自动加1或由转移指针给出下一条指令的地址。
此后经过分析指令,执行指令。
完成第一条指令的执行,而后根据PC取出第二条指令的地址,如此循环,执行每一条指令。
处理器的程序计数器是指寄存器,而java程序计数器是指一小块内存空间。
java代码编译字节码之后,虚拟机会一行一行的解释字节码,并翻印成本地代码。
这个程序计数器盛放的就是当前线程所执行字节码的行号的指示器。
在虚拟机概念模型中,字节码解释器工作室就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支,循环,跳转,异常处理等都依赖于它。
Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式实现的,因此为了线程切换后还能恢复执行位置,每条线程都需要一个独立的程序计数器。
如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果执行的是Java Native方法,这个计数器值为空。
而且程序计数器是Java虚拟机中没有规定任何OutOfMemoryError的区域。
(2)虚拟机栈Java虚拟机栈(VM Stack)也是线程私有的,因此它的生命周期也和线程相同。
它存放的是Java方法执行时的数据,既描述的是Java方法执行的内存模型:每个方法开始执行的时候,都会创建一个栈帧(Stack Frame)用于储存局部变量表、栈操作数、动态链接、方法出口等信息。
每个方法从调用到执行完成就对应一个栈帧在虚拟机栈中入栈到出栈的过程。
经常有人把Java内存分为堆内存和栈内存,这种是比较粗糙的分法,很大原因是大多数程序‘猿’最关注的,与对象内存分配最密切的区域就是堆和栈。
局部变量表存放的是编译器可知的各种基本数据类型(boolean 、byte、int、long、char、short、float、double)、对象引用(reference类型)和returnAddress类型(它指向了一条字节码指令的地址)。
其中64bit长度的long和double会占用两个局部变量空间(Slot),其余的数据类型只占用一个。
局部变量表所需的内存空间是在编译时期确定的,在方法运行期间不会改变局部变量表的大小。
在Java虚拟机规范中,对这部分区域规定了两种异常:1、当一个线程的栈深度大于虚拟机所允许的深度的时候,将会抛出StackOverflowError异常; 2、如果当创建一个新的线程时无法申请到足够的内存,则会抛出OutOfMemeryError异常。
(3)本地方法栈本地方法栈(Native Method Stack)与虚拟机栈所发挥的作用是十分相似的,他们之间的区别不过是虚拟机栈为Java方法字节码服务,而本地方法栈则为Native方法服务。
在虚拟机规范中对本地方法使用的语言和使用方法与数据结构没有强制规定,因此具体的虚拟机可以自由实现它。
Sun HotSpot虚拟机把本地方法栈和虚拟机栈合二为一。
和虚拟机栈一样,本地方法栈也会抛出OutOfMemoryError和StackOverflowError异常。
接下来我们介绍的都是所有线程共享的区域了。
(4)堆(heap)堆是虚拟机中最大的一块内存区域了,被所有线程共享,在虚拟机启动时创建。
它的目的便是存放对象实例。
堆是垃圾收集器管理的主要区域,因此很多时候也被成为‘GC’堆(Garbage Collected Heap)。
从垃圾回收的角度来讲,现在的收集器包括HotSpot都采用分代收集算法,所以堆又可以分为:新生代(Young)和老年代(Tenured),再细致一点,新生代又可分为Eden、From Survivor 空间和To Survivor空间。
从内存分配的角度来讲,又可以分为若干个线程私有的分配缓冲区(Thread Local Allocation Buffer ,TLAB)。
当堆空间不足切无法扩展,会抛出OutOfMemoryError异常。
(5)方法区(Method Area)与Java堆一样,是各个线程共享的内存区域,用于存储被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
它有个别名叫做非堆Non-Heap。
对于HotSpot 开发者来说,很多人称它为“永久代”(Permanent Generation),但是两者并不等价,仅仅是因为HotSpot虚拟机设计团队把GC分代收集扩展至方法区,或者说使用永久代来实现方法区而已,这样HotSpot的垃圾收集器可以向管理堆一样管理这部分内存。
但是因为永久代有“-XX:MaxPermSize的上限,使其更容易内存溢出。
因此在JDK1.7的HotSpot中,已经把原本放在永久代的字符串常量池移出去了。
当方法区无法满足内存分配需求的时候,会抛出OutOfMemoryError异常。
(6)常量池运行时常量池(Runtime Constant Pool)是方法区的一部分。
Class文件中出了类的版本、字段、方法、接口等信息外,还有一项信息是常量池(Constant Pool Table),用于存放编译器生成的各种字面量和符号引用,这些内容将在类加载后进入方法区存放。
运行时常量池相对于Class文件常量池的另外一个重要特征是具有动态性,运行期间也可能有新的常量池放入持重,比如String.intern()方法。
运行时常量池属于方法区一部分,自然会抛出OutOfMemoryError异常。
(7)直接内存直接内存(Direct Memory)不属于虚拟机中定义的内存区域,而是堆外内存。
JDK1.4 中新加入了NIO(new Input/Output)类,引入了一种基于通道(Channel)和缓冲区(Buffer)的I/O方式,它可以使用Native函数直接分配堆外内存,然后通过Java堆中的DirectByteBuffer对象作为这快内存的引用进行操作。
这样能在一些场景中显著提高新能性能。
如果直接内存不足时,会抛出OutOfMemoryError异常。
GC在什么时候对什么做了什么?要回答这个问题,先了解下GC的发展史、jvm运行时数据区的划分、jvm内存分配策略、jvm垃圾收集算法等知识。
先说下jvm运行时数据的划分,粗暴的分可以分为堆区(Heap)和栈区(Stack),但jvm 的分法实际上比这复杂得多,大概分为下面几块:1、程序计数器(Program Conuter Register)程序计数器是一块较小的内存空间,它是当前线程执行字节码的行号指示器,字节码解释工作器就是通过改变这个计数器的值来选取下一条需要执行的指令。
它是线程私有的内存,也是唯一一个没有OOM异常的区域。
2、Java虚拟机栈区(Java Virtual Machine Stacks)也就是通常所说的栈区,它描述的是Java方法执行的内存模型,每个方法被执行的时候都创建一个栈帧(Stack Frame),用于存储局部变量表、操作数栈、动态链接、方法出口等。
每个方法被调用到完成,相当于一个栈帧在虚拟机栈中从入栈到出栈的过程。
此区域也是线程私有的内存,可能抛出两种异常:如果线程请求的栈深度大于虚拟机允许的深度将抛出StackOverflowError;如果虚拟机栈可以动态的扩展,扩展到无法动态的申请到足够的内存时会抛出OOM异常。
3、本地方法栈(Native Method Stacks)本地方法栈与虚拟机栈发挥的作用非常相似,区别就是虚拟机栈为虚拟机执行Java方法,本地方法栈则是为虚拟机使用到的Native方法服务。
4、堆区(Heap)所有对象实例和数组都在堆区上分配,堆区是GC主要管理的区域。
堆区还可以细分为新生代、老年代,新生代还分为一个Eden区和两个Survivor区。
此块内存为所有线程共享区域,当堆中没有足够内存完成实例分配时会抛出OOM异常。
5、方法区(Method Area)方法区也是所有线程共享区,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。
GC在这个区域很少出现,这个区域内存回收的目标主要是对常量池的回收和类型的卸载,回收的内存比较少,所以也有称这个区域为永久代(Permanent Generation)的。
当方法区无法满足内存分配时抛出OOM异常。
6、运行时常量池(Runtime Constant Pool)运行时常量池是方法区的一部分,用于存放编译期生成的各种字面量和符号引用。
垃圾收集(Garbage Collection)并不是Java独有的,最早是出现在Lisp语言中,它做的事就是自动管理内存,也就是下面三个问题:1、什么时候回收2、哪些内存需要回收3、如何回收1、什么时候回收?上面说到GC经常发生的区域是堆区,堆区还可以细分为新生代、老年代,新生代还分为一个Eden区和两个Survivor区。
1.1对象优先在Eden中分配,当Eden中没有足够空间时,虚拟机将发生一次Minor GC,因为Java大多数对象都是朝生夕灭,所以Minor GC非常频繁,而且速度也很快;1.2 Full GC,发生在老年代的GC,当老年代没有足够的空间时即发生Full GC,发生Full GC一般都会有一次Minor GC。
大对象直接进入老年代,如很长的字符串数组,虚拟机提供一个-XX:PretenureSizeThreadhold参数,令大于这个参数值的对象直接在老年代中分配,避免在Eden区和两个Survivor区发生大量的内存拷贝;1.3发生Minor GC时,虚拟机会检测之前每次晋升到老年代的平均大小是否大于老年代的剩余空间大小,如果大于,则进行一次Full GC,如果小于,则查看HandlePromotionFailure设置是否允许担保失败,如果允许,那只会进行一次Minor GC,如果不允许,则改为进行一次Full GC。