jrockit

Java运行时数据区域

半腔热情 提交于 2020-12-18 04:24:41
   Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域都有各自不同的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁。根据《Java虚拟机规范(Java SE 7版)》的规定,Java虚拟机所管理的内存将会包括以下几个运行时数据区域: 1. 程序计数器   程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里(仅是概念模型,各种虚拟机可能会通过一些更高效的方式去实现),字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。   由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。   如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的事Native方法

Java虚拟机一:运行时数据区域

霸气de小男生 提交于 2020-11-30 23:45:40
  java虚拟机在执行java程序的过程中,会把内存划分为若干个不同的数据区域。每个区域都有各自的用途,创建和销毁时间,按照《java虚拟机规范(Java SE 7 版)》的规定,虚拟机运行时数据区域主要有以下几种: 1.程序计数器   程序计数器是很小的一块内存区域,可以看做是当前线程所执行字节码的行号指示器。在虚拟机的概念模型中,字节码解释器工作时就是通过改变程序计数器的值来选取下一条需要执行的字节码指令,分支,循环,跳转,异常处理,线程恢复等基础功能均依赖于程序计数器。在多线程中,每个线程都有一个独立的程序计数器,每个线程的程序计数器之间互不影响,即“线程私有”。同时,程序计数器是java虚拟机规范中唯一一个没有规定OutOfMemoryError的区域。 2.java虚拟机栈   虚拟机栈描述的是java方法执行的内存模型,每个方法在执行时候都会创建一个栈帧用于存储局部变量表,操作数栈,动态链接,方法出口等信息。每个方法从被调用执行到执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。虚拟机栈也是线程私有的。在Java虚拟机规范中,虚拟机栈有两种异常状况: (1)线程请求的栈深度大于虚拟机栈所允许的深度,将抛出StackOverflowError异常; (2)如果虚拟机栈可以动态扩展,但扩展时无法申请到足够的内存

JVM中的新生代、老年代和永生代

谁都会走 提交于 2020-11-21 12:25:31
1.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能。你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我们要找到哪些对象没用,这样就会对堆的所有区域进行扫描。而我们的很多对象都是朝生夕死的,如果分代的话,我们把新创建的对象放到某一地方,当GC的时候先把这块存“朝生夕死”对象的区域进行回收,这样就会腾出很大的空间出来。 2.年轻代中的GC HotSpot JVM把年轻代分为了三部分:1个Eden区和2个Survivor区(分别叫from和to)。默认比例为8:1,为啥默认会是这个比例,接下来我们会聊到。一般情况下,新创建的对象都会被分配到Eden区(一些大对象特殊处理),这些对象经过第一次Minor GC后,如果仍然存活,将会被移到Survivor区。对象在Survivor区中每熬过一次Minor GC,年龄就会增加1岁,当它的年龄增加到一定程度时,就会被移动到年老代中。 因为年轻代中的对象基本都是朝生夕死的(80%以上),所以在年轻代的垃圾回收算法使用的是复制算法,复制算法的基本思想就是将内存分为两块,每次只用其中一块,当这一块内存用完,就将还活着的对象复制到另外一块上面。复制算法不会产生内存碎片。 在GC开始的时候,对象只会存在于Eden区和名为“From”的Survivor区

JVM 的 GC 简单知识

喜欢而已 提交于 2020-10-24 08:37:22
JVM 内容 在 jvm 中内存大概可以这样划分。(1.6 和1.8 有些区别) 我们经常看到的 “PermGen space” 其实指的就是方法区。不过方法区和“PermGen space”又有着本质的区别。前者是JVM的规范,而后者则是JVM规范的一种实现,并且只有HotSpot才有“PermGen space”,而对于其他类型的虚拟机,如JRockit(Oracle)、J9(IBM)并没有“PermGen space”。 PS:以上图片取自 https://www.pianshen.com/article/9674355417/ (侵删) 在java 1.8之后,方法区就被移除了,替换的是metaspace,这个在 Metaspace 有介绍。 Heap heap的唯一目的就是存放对象实例,几乎所有的对象实例以及数组都在这里分配内存。 进一步看 heap的划分。 大部分情况,对象都会首先在 Eden 区域分配,在一次新生代垃圾回收后,如果对象还存活,则会进入 s0 或者 s1,并且对象的年龄还会加 1(Eden区->Survivor 区后对象的初始年龄变为1),当它的年龄增加到一定程度(默认为15岁),就会被晋升到老年代中。对象晋升到老年代的年龄阈值,可以通过参数 -XX:MaxTenuringThreshold 来设置。 GC 本文简单讲述一下gc的类型及触发条件

【JVM之内存与垃圾回收篇】JVM与Java体系结构

大兔子大兔子 提交于 2020-08-16 12:18:52
JVM与Java体系结构 前言 作为 Java 工程师的你曾被伤害过吗?你是否也遇到过这些问题? 运行着的线上系统突然卡死,系统无法访问,甚至直接 OOM(out of memory)! 想解决线上 JVM GC 问题,但却无从下手。 新项目上线,对各种 JVM 参数设置一脸茫然,直接默认吧然后就 GG 了 每次面试之前都要重新背一遍 JVM 的一些原理概念性的东西,然而面试官却经常问你在实际项目中如何调优 VM 参数,如何解决 GC、OOM 等问题,一脸懵逼。 大部分 Java 开发人员,除会在项目中使用到与 Java 平台相关的各种高精尖技术,对于 Java 技术的核心 Java 虚拟机了解甚少。 一些有一定工作经验的开发人员,打心眼儿里觉得 SSM、微服务等上层技术才是重点,基础技术并不重要,这其实是一种本末倒置的“病态”。如果我们把核心类库的 API 比做数学公式的话,那么 Java 虚拟机的知识就好比公式的推导过程。 计算机系统体系对我们来说越来越远,在不了解底层实现方式的前提下,通过高级语言很容易编写程序代码。但事实上计算机并不认识高级语言 架构师每天都在思考什么? 应该如何让我的系统更快? 如何避免系统出现瓶颈? 知乎上有条帖子:应该如何看招聘信息,直通年薪 50万+? 参与现有系统的性能优化,重构,保证平台性能和稳定性 根据业务场景和需求,决定技术方向,做技术选型

Java内存区域(运行时数据区域)和内存模型(JMM)

牧云@^-^@ 提交于 2020-08-15 13:28:19
Java 内存区域和内存模型是不一样的东西,内存区域是指 Jvm 运行时将数据分区域存储,强调对内存空间的划分。 而内存模型(Java Memory Model,简称 JMM )是定义了线程和主内存之间的抽象关系,即 JMM 定义了 JVM 在计算机内存(RAM)中的工作方式,如果我们要想深入了解Java并发编程,就要先理解好Java内存模型。 Java运行时数据区域 众所周知,Java 虚拟机有自动内存管理机制,如果出现内存泄漏和溢出方面的问题,排查错误就必须要了解虚拟机是怎样使用内存的。 下图是 JDK8 之后的 JVM 内存布局。 JDK8 之前的内存区域图如下: 在 HotSpot JVM 中,永久代中用于存放类和方法的元数据以及常量池,比如 Class 和 Method 。每当一个类初次被加载的时候,它的元数据都会放到永久代中。 永久代是有大小限制的,因此如果加载的类太多,很有可能导致永久代内存溢出,即万恶的 java.lang.OutOfMemoryError: PermGen ,为此我们不得不对虚拟机做调优。 那么,Java 8 中 PermGen 为什么被移出 HotSpot JVM 了?我总结了两个主要原因: 由于 PermGen 内存经常会溢出,引发恼人的 java.lang.OutOfMemoryError: PermGen ,因此 JVM

JIT与JVM的三种执行模式:解释模式、编译模式、混合模式

北战南征 提交于 2020-08-12 18:17:00
Java JIT(just in time)即时编译器是sun公司采用了hotspot虚拟机取代其开发的classic vm之后引入的一项技术,目的在于提高java程序的性能,改变人们“java比C/C++慢很多”这一尴尬印象。 说起来是编译器,但此编译器与通常说的javac那个编译器不同,它其实是将字节码编译为硬件可执行的机器码的。 图片来自于网络 如上图可以看出,整个java应用程序的执行过程如下: 1、源代码经javac编译成字节码,class文件 2、程序字节码经过JIT环境变量进行判断,是否属于“热点代码”(多次调用的方法,或循环等) 3、如是,走JIT编译为具体硬件处理器(如sparc、intel)机器码 4、如否,则直接由解释器解释执行 5、操作系统及类库调用 6、硬件 以上实际上是JVM的“混合模式”对java程序的执行方式。 jvm还有两种执行方式: 解释执行和编译执行 对于解释执行,不经过jit直接由解释器解释执行所有字节码,执行效率不高。 而编译执行不加筛选的将全部代码进行编译机器码不论其执行频率是否有编译价值,在程序响应时间的限制下,编译器没法采用编译耗时较高的优化技术(因为JIT的编译是首次运行或启动的时候进行的!),所以,在纯编译执行模式下的java程序执行效率跟C/C++也是具有较大差距的。 因此,新版本的jvm默认都是采用混合执行模式。

JAVA内存模型

好久不见. 提交于 2020-08-12 04:58:45
JAVA内存模型 线程角度 程序计数器(Program Counter Register) 当前程序所执行的字节码行号指示器(逻辑) 改变计数器的值来选取下一条需要执行的字节码指令 和线程是一对一的关系即“线程私有”,一个明确的时间点,处理器只会执行一个线程的代码,就需要其他线程存储自己的程序计数器,以便处理器在切换线程的时候,可以继续执行上次未执行完的逻辑。 对java方法计数,如果正在执行的方法是native方法则计数器值为undefined 因为只是记录行号,程序计数器不必担心内存泄漏的问题 JAVA虚拟机栈(Stack) JAVA方法执行的内存模型 包含多个栈帧 局部变量表和操作数栈 局部变量表:包含方法执行过程中的所有变量 操作数栈:入栈、出栈、复制、交换、产生消费变量。栈模型,先进后出,当方法中调用其他方法,那么也是后调用的方法先执行完,才会执行外层的方法,这就符合了栈模型。 递归为什么会引发java.lang.StackOverflowError异常? 虚拟机栈过多会引发java.lang.OutOfMemoryError异常 本地方法栈 与虚拟机相似,主要作用于标准了native的方法。 元空间(MetaSpace)与永久代(PermGen)的区别 元空间直接使用本地内存,而永久代使用JVM内存。好处:本地内存剩余多少,元空间就有多大,元空间的数据不再占用JVM内存

深入理解Java虚拟机--个人总结(持续更新)

人盡茶涼 提交于 2020-08-08 18:21:26
深入理解Java虚拟机--个人总结(持续更新) 每天按照书本学一点,会把自己的总结思考写下来,形成输出,持续更新,立帖为证 -- 2020年7月7日 开始第一次学习 -- 2020年7月8日 今天在百忙Rush B中抽出时间,学了点习,计划明天把本地方法栈和Java堆看完总结完 -- 2020年7月10日 第一次周五学习,也算是有进步,翻了一下书感觉好多啊,不知道什么时候能看完 -- 2020年7月15日 冲鸭!!!! 第二部分、自动内存管理 一、Java内存区域与内存溢出异常 Java与C++在内存控制方面截然不同,因为Java虚拟机有自动内存管理机制,所以Java程序员就牺牲部分内存控制权,来换取编写程序时的便利。虽然不容易出现内存泄漏和内存溢出问题,但还是有必要学习点Java虚拟机相关知识,除了在遇到虚拟机问题时可以快速解决之外,还可以和别人装逼(最大的快乐!) Java虚拟机在运行Java程序的时候,会将内存自动划分为不同区域,不同区域对应的功能、创建销毁时间也不同,有些区域会随着虚拟机启动而一直存在,有些区域以来用户的线程启动结束而创建销毁。 内存区域分为以下几个区域: 程序计数器 Java虚拟机栈 本地方法栈 Java堆 方法区 运行时常量池 直接内存 程序计数器 程序计数器是 :一小块内存空间, 记录当前线程执行字节码指令的地址

Java内存区域(运行时数据区域)和内存模型(JMM)

扶醉桌前 提交于 2020-08-06 10:11:58
Java 内存区域和内存模型是不一样的东西,内存区域是指 Jvm 运行时将数据分区域存储,强调对内存空间的划分。 而内存模型(Java Memory Model,简称 JMM )是定义了线程和主内存之间的抽象关系,即 JMM 定义了 JVM 在计算机内存(RAM)中的工作方式,如果我们要想深入了解Java并发编程,就要先理解好Java内存模型。 Java运行时数据区域 众所周知,Java 虚拟机有自动内存管理机制,如果出现内存泄漏和溢出方面的问题,排查错误就必须要了解虚拟机是怎样使用内存的。 下图是 JDK8 之后的 JVM 内存布局。 JDK8 之前的内存区域图如下: 在 HotSpot JVM 中,永久代中用于存放类和方法的元数据以及常量池,比如 Class 和 Method 。每当一个类初次被加载的时候,它的元数据都会放到永久代中。 永久代是有大小限制的,因此如果加载的类太多,很有可能导致永久代内存溢出,即万恶的 java.lang.OutOfMemoryError: PermGen ,为此我们不得不对虚拟机做调优。 那么,Java 8 中 PermGen 为什么被移出 HotSpot JVM 了?我总结了两个主要原因: 由于 PermGen 内存经常会溢出,引发恼人的 java.lang.OutOfMemoryError: PermGen ,因此 JVM