Java内存机制详解|JVM初步

Java内存机制详解|JVM初步

[TOC]

JVM

JVM执行引擎

  • 解释器
  • JIT(Just In Time),优先次执行的字节码会编译成本地的机器代码,被缓存在系统中,以后可以随时调用
  • 自适应的优化器,虚拟机开始的时候解释字节码CodeGo.net,但是会监控运行中程序的活动,并记录下使用最频繁的代码段,虚拟机会把这些活动最频繁的代码段编译成本地代码。还有一种虚拟机是由硬件芯片构成,它用本地方法执行java字节码

JVM程序执行过程

  1. 加载.class文件
  2. 管理分配内存
  3. 执行垃圾收集

JVM生命周期

  1. 启动
    启动一个Java 程序时,一个JVM 实例就产生了,任何一个又有 public static void main(String[] args) 函数的class 文件都可以作为JVM 实例运行的起点。
  2. 运行
    main()作为该程序初始线程的起点,任何其他线程均由该线程启动。JVM 内部有两种线程:守护线程和非守护线程,main()属于非守护线程,守护线程通常由JVM 自己使用,java 程序也可以表明自己创建的线程是守护线程。
  3. 消亡
    当程序中的所有非守护线程都终止时,JVM 才退出;若安全管理器允许,程序也可以使用Runtime类或者System.exit()来退出。

JVM的逻辑内存模型

(重点重点[敲黑板],仔细查看外链博客[敲黑板])

JVM的逻辑内存模型

深入理解JVM—JVM内存模型

方法区:方法区(Method Area)与Java 堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。虽然Java 虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做Non-Heap(非堆),目的应该是与Java 堆区分开来。
要注意方法区单独开辟,不同于堆内存,意在一些类的公共的方法可以共享,堆内对象还有引用指向方法区。

运行时常量池:运行时常量池(Runtime Constant Pool)是方法区的一部分。Class 文件中除了有类的版本、字段、方法、接口等描述等信息外。还有一项信息是常量池(Constant PoolTable),用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。

常量池(ConstantPool):常量池在编译期间就将一部分数据存放于该区域,包含基本数据类型如int、long等和对象类型String、数组等并以final声明的常量值。特别注意的是对于运行期位于栈中的String常量的值可以通过 String.intern()方法将该值置入到常量池中。

JVM体系结构

JVM体系结构

内存分配及变量存储位置(堆、栈、方法区常量池、方法区静态区)

返回值:会在栈空间中临时开辟一块空间临时存放,在方法执行完成后消失。

JVM原理

JVM原理

堆内存和栈内存

栈内存

当在一段代码块定义一个变量时,Java 就在栈中为这个变量分配内存空间。栈中主要存放一些基本类型的变量(int, short, long, byte, float,double, boolean, char)和对象句柄。
栈有一个很重要的特殊性,就是存在栈中的数据可以共享。

堆内存

堆内存用来存放由new 创建的对象和数组

eg
假设我们同时定义:
int a = 3;
int b = 3;
编译器先处理int a = 3;首先它会在栈中创建一个变量为a 的引用,然后查找栈中是否有3 这个值,如果没找到,就将3 存放进来,然后将a 指向3。接着处理int b = 3;在创建完b 的引用变量后,因为在栈中已经有3 这个值,便将b 直接指向3。这样,就出现了a 与b 同时均指向3 的情况。这时,如果再令a=4;那么编译器会重新搜索栈中是否有4 值,如果没有,则将4 存放进来,并令a 指向4;如果已经有了,则直接将a 指向这个地址。因此a 值的改变不会影响到b 的值。要注意这种数据的共享与两
个对象的引用同时指向一个对象的这种共享是不同的,因为这种情况a 的修改并不会影响到b,它是由编译器完成的,它有利于节省空间。而一个对象引用变量修改了这个对象的内部状态,会影响到另一个对象引用变量。

String 是一个特殊的包装类数据。可以用:
String str = new String("abc");
String str = "abc";
两种的形式来创建,第一种是用new()来新建对象的,它会在存放于堆中。每调用一次就会创建一个新的对象。而第二种是先在栈中创建一个对String 类的对象引用变量str,然后查找栈中有没有存放"abc",如果没有,则"abc"存放进栈,并令str 指向"abc",如果已经有"abc"则直接令str 指向"abc"

JVM 垃圾回收

GC (Garbage Collection)的基本原理:
将内存中不再被使用的对象进行回收,GC 中用于回收的方法称为收集器,由于GC 需要消耗一些资源和时间,Java 在对对象的生命周期特征进行分析后,按照新生代、旧生代的方式来对对象进行收集,以尽可能的缩短GC 对应用造成的暂停。

java 虚拟机会在6 种情况下创建一个对象

  1. 创建类的新实例
  2. 调用类中声明的静态方法
  3. 操作类或接口中声明的非常量静态字段
  4. 调用Java API 中特定的反射方法
  5. 初始化一个类的子类
  6. 制定一个类作为Java 虚拟机启动时的初始化类
文章作者: HibisciDai
文章链接: http://hibiscidai.com/2017/07/15/2017-07-15-Java内存机制详解JVM初步/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 HibisciDai
支付宝打赏
微信打赏