JAVA JVM 杂谈(一)
JVM能够跨计算机体系结构来执行Java字节码,主要是由于JVM屏蔽了与各个计算机平台先关的软件或者硬件之间的差异,使得与平台先关的耦合统一由JVM的提供者来实现。
JVM结构组成:
1.类加载器:在JVM启动时或者在类运行时将需要的class加载到JVM中。
2.执行引擎:执行引擎的任务是负责执行class文件中包含的字节码指令,相当于实际机器上的CPU。
3.内存区:将内存划分成若干个区以模拟实际机器上的存储、记录和调度功能模块,如实际机器上的各种功能的寄存器或者PC指针的记录器等。
4.本地方法调用:调用C或C++实现的本地方法代码返回结果。

一.类加载器
ClassLoader:
1.负责将Class加载到JVM中。2.审查每个类该由谁加载,它是一种父优先级等级加载机制。3.将Class字节码重新解析成JVM统一要求的格式。
JVM加载class文件到内存有两种方式
隐式加载:所谓隐式加载就是不通过在代码里调用ClassLoader来加载需要的类,而是通过JVM来自动加载需要的类到内存的方式。例如,当我们在类中继承或者引用某个类时,JVM在解析当前这个类时发现引用的类不在内存中,那么就会自动将这些类加载到内存中。
显示加载:相反的显示加载就是我们在代码中通过调用ClassLoader类来加载一个类的方式,例如,调用this.getClass.getClassLoader().loadClass()或者Class.forName();
三种ClassLoader:
1.BootstrapClassLoader:主要加载JVM自身工作需要的类,这个ClassLoader完全是JVM自己控制的,需要加载哪个类、怎么加载都是由JVM自己控制,别人也访问不到这个类,它仅仅是一个类的加载工具而已,既没有更高一级的父加载器,也没有子加载器。
2.ExtClassLoader:扩展类加载器,它会加载System.getProperty("java.ext.dirs")目录下的文件。
3.AppClassLoader:它的父类是ExtClassLoader,所有在System.getProperty("java.class.path")目录下的类都可以被这个类加载器加载,这个目录就是经常用到的classpath。
如果我们要实现自己的类加载器,不管你是直接实现抽象类ClassLoader,还是继承URLClassLoader类,或者其他子类,它的父加载器都是AppClassLoader,因为不管调用哪个父类构造器,创建的对象都必须最终调用getSystemClassLoader()作为父加载器。而getSystemClassLoader()方法获取的正是AppClassLoader。
一个ClassLoader加载class到JVM中的步骤:

第一个阶段是找到 .class文件并把这个文件包含的字节码加载到内存中。
第二个阶段又可以分为三个步骤,分别是字节码验证、Class类数据结构分析及相应的内存分配和最后的符号表的连接。
第三个阶段是类静态属性和初始化赋值,以及静态块的执行。
二.执行引擎
执行引擎是JVM的核心部分,执行引擎的作用就是解析JVM字节码指令,得到执行结果。JVM执行引擎采用什么方式实现,由实现厂家自己决定。如SUN的hotspot是基于栈的执行引擎,而Google的Dalvik是基于寄存器的执行引擎。
三.JVM运行时数据区
JVM虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁。

程序计数器:它是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。程序计数器是线程私有的内存,每条线程都有一个程序计数器,这样在多线程执行线程切换回来后,才能保证恢复到正确的执行位置。如果线程正在执行的是一个JAVA方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,则计数器值则为空。此内存区域是唯一一个在java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。
JAVA虚拟机栈:java虚拟机栈也是一个线程私有的,它的生命周期与线程相同。虚拟机栈描述的是java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。在JAVA虚拟机规范中,对这个区域规定了两种异常状况:如果线程请求的栈深度大于虚拟机所允许的深度,将会抛出StackOverflowError异常;如果虚拟机可以动态扩展,当扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。
本地方法栈:与虚拟机栈所发挥的作用非常相似,它们之间的区别不过是虚拟机栈为虚拟机执行java方法服务,而本地方法栈则为虚拟机使用到的Native方法服务。同样也会抛出StackOverflowError和OutOfMemoryError异常,也是一个线程私有的。
java堆:java堆是java虚拟机所管理的内存中最大的一块,是被所有线程共享的一块内存区域,在虚拟机启动时创建。所有的对象实例以及数组都要在堆上分配。(java堆是垃圾收集器管理的主要区域)。
方法区:是一个被所有线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译过后的代码等数据。当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。
运行时常量池(方法区的一部分):用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。
未完待续。
JAVA JVM 杂谈(一)的更多相关文章
- Java (JVM) Memory Model – Memory Management in Java
原文地址:http://www.journaldev.com/2856/java-jvm-memory-model-memory-management-in-java Understanding JV ...
- JAVA JVM虚拟机选项:Xms Xmx PermSize MaxPermSize 区别
Xms : 是指设定程序启动时占用内存大小.一般该值设置大的会使程序启动快,但是可能会使本机暂时变慢. Xmx : 是指设定程序运行期间最大可占用的内存大小,如果程序运行需要占用更多的内存,超出这个 ...
- Java JVM、JNI、Native Function Interface、Create New Process Native Function API Analysis
目录 . JAVA JVM . Java JNI: Java Native Interface . Java Create New Process Native Function API Analys ...
- Java多线程学习笔记——从Java JVM对多线程数据同步的一些理解
我们知道在多线程编程中,我们很大的一部分内容是为了解决线程间的资源同步问题和线程间共同协作解决问题.线程间的同步,通俗我们理解为僧多粥少,在粥有限情况下,我们怎么去防止大家有秩序的喝到粥,不至于 ...
- Java JVM 多态(动态绑定)
Java JVM 多态(动态绑定) @author ixenos 摘要:绑定.动态绑定实现多态.多态的缺陷.纯继承与扩展接口.向下转型与RTTI 绑定 将一个方法的调用和一个方法的主体关联起来,称作( ...
- Java JVM 内存泄漏--全解析和处理办法 [ 转载 ]
Java JVM 内存泄露——全解析和处理办法 [转载] @author 小筐子 @address http://www.jianshu.com/p/bf159a9c391a JA ...
- Java JVM使用哪种编码格式
Java JVM使用哪种编码格式 A ASCII characters B Unicode characters C Cp1252 D UTF-8 E GBK F GBK2312 答案:B 在J ...
- Apache Curator is a Java/JVM client library for Apache ZooKeeper
http://curator.apache.org/index.html Welcome to Apache Curator What is Curator? Curator n ˈkyoor͝ˌāt ...
- Java JVM监控工具JConsole简介
Java JVM监控工具JConsole简介 jconsole命令 功能:打开java监视管理控制台 方法: jconsole [选项1] [选项2] …… [选项n] 常用选项: -help ...
随机推荐
- 30-Transformation(HDU4578)-区间线段树(复杂)
http://acm.hdu.edu.cn/showproblem.php?pid=4578 Transformation Time Limit: 15000/8000 MS (Java/Others ...
- SpringBoot全局异常的捕获设置
1.新建立一个捕获异常的实体类 如:LeeExceptionHandler package com.leecx.exception; import javax.servlet.http.HttpSer ...
- Linux下Maven的安装与使用
pache Maven,是一个软件(特别是Java软件)项目管理及自动构建工具,由Apache软件基金会所提供.基于项目对象模型(POM)概念,Maven利 用一个中央信息片断能管理一个项目的构建.报 ...
- 1、SSH框架整合
1.建立项目 2.导入SSHjar包 http://pan.baidu.com/s/1hsELr04 3.引入web.xml文件 <?xml version="1.0" en ...
- python2.7 跨文件全局变量的方法-乾颐堂
在使用Python编写的应用的过程中,有时会遇到多个文件之间传递同一个全局变量的情况. 文件1:globalvar.py 1 2 3 4 5 6 7 8 9 10 11 12 #!/usr/bin/e ...
- 使用UrlRewriteFilter对url进行更替
一般来说,使用struts之后url的访问实际上访问的是action的地址,为了不让该地址暴露给别人,可以采用UrlRewriteFilter来对url进行重写. 首先,在web.xml里面配置: & ...
- mysql:unknown variable 'default -collation=utf8_general_ci'
无法登陆,因为在配置文档中设置了默认编码方式 将它注释掉,问题就解决了 在utf8_bin中你就找不到 txt = 'A' 的那一行, 而 utf8_general_ci 则可以.utf8_gener ...
- Thinkphp 导出csv 先存储在服务器,然后输出链接下载
public function exportQiandao() { // header("Content-type:text/html;charset=gb2312"); ini_ ...
- Thinkphp 导出大量数据 csv格式
public function test2() { $user_count = M('department')->count(); $page = ceil($user_count / 1000 ...
- C++11中的to_string
C++11之前,标准库没有提供数字类型转字符串的函数,需要借助sprintf.stringstream等,现在C++11提供了std::to_string函数,可以直接使用了: 点击(此处)折叠或打开 ...