CODY

CODY 关注TA

一坑未平,一坑起

CODY

CODY

关注TA

一坑未平,一坑起

  •  深圳南山
  • java酱油党
  • 写了59,448字

该文章投稿至Nemo社区   Java  板块 复制链接


JVM概要二

发布于 2017/09/01 17:28 1,569浏览 4回复 2,496

一. JVM概念

Java虚拟机,JAVA程序自己独立运行环境;  有自己完善的硬件架构,如类加载器、堆栈、寄存器等,还具有相应的指令系统


二 .JVM 原理

Java源文件经javac编译器,编译成字节码程序,通过JVM执行引擎将每一条指令翻译成不同平台机器码,通过特定平台运行。

java编译器只需面向JVM,生成JVM能理解的代码或字节码文件。这也是java能跨平台,“一次编译,到处运行”的原因

 原理图: 

三. JVM组成

主要由类加载器子系统运行时数据区(内存空间)执行引擎以及与本地方法接口等组成。

模型:

    

四. JVM组成--类加载器 

1)Bootstrap ClassLoader(启动类加载器)

负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类

2)Extension ClassLoader(标准扩展类加载器)

负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包

3)App ClassLoader(应用程序类加载器)

负责将系统类路径classpath中指定的jar包及目录中class加载到内存

4)Custom ClassLoader(自定义类加载器)

属于应用程序根据自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行实现ClassLoader


五. JVM组成--运行时数据区

包括:栈、堆、方法区、pc寄存区、本地方法栈

名称

特征

作用

配置参数

异常

程序计数器

占用内存小,线程私有,
生命周期与线程相同

多线程下,为了记录线程的执行情况,便于下次切换后进行线程恢复

java栈

线程私有,生命周期与线程相同,使用连续的内存空间

主要存放 局部变量、基本类型的变量和对象的引用变量
-Xss

StackOverflowError
OutOfMemoryError

java堆

线程共享,生命周期与虚拟机相同

主要存放存放由new创建的对象和数组
-Xms
-Xsx
-Xmn

OutOfMemoryError

方法区

线程共享,生命周期与虚拟机相同

存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据

-XX:PermSize:
16M
-XX:MaxPermSize:
64M

OutOfMemoryError

常量池

方法区(1.7前)/堆(1.7后)的一部分,具有动态性

存放常量量

 

 

模型图:


六. 堆内存

概要

堆内存划分为三个代:年轻代(Young Generation)、老年代(Old Generation)和持久代(Permanent Generation)也就是常量池

模型图


年轻代

·所有新生成的对象首先都是放在年轻代的。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象

·年轻代分三个区。一个Eden区,一个Survivor(from/to)幸存区,默认8:1:1

·过程:

当Eden区满时,还存活的对象将被复制到Survivor区(两个中的一个),当这个Survivor区满时,此区的存活对象将被复制到另外一个Survivor区,当这个Survivor去也满了的时候,从第一个Survivor区复制过来的并且此时还存活的对象,将被复制“年老区(Tenured)”。

·注意:

Survivor的两个区是对称的,没先后关系,但复制到年老区的只有从第一个Survivor去过来的对象

老年代

在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象

持久代

就是1.8后的常量池,用于存放静态文件,如今Java类、方法等。持久代对垃圾回收没有显著影响

Scavenge GC

当新对象生成,并且在Eden申请空间失败时,就会触发Scavenge GC,对Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区。然后整理Survivor的两个区。这种方式的GC是对年轻代的Eden区进行,不会影响到年老代

Eden区的GC会频繁进行

Full GC

·对整个堆进行整理,包括Young、Tenured和Perm

·Full GC因为需要对整个对进行回收,所以比Scavenge GC要慢,因此应该尽可能减少Full GC的次数

·导致原因

 年老代(Tenured)被写满

 持久代(Perm)被写满

 System.gc()被显示调用

 上一次GC之后Heap的各域分配策略动态变化


七. JVM常见参数配置

内存

参数

作用

说明

 

GC

-verbose:gc -XX:+PrintGCDetails

打印GC日志信息

 

 

-Xloggc:d:/gc.log

GC日志文件目录

 

-XX:+PrintHeapAtGC

打印堆信息(每一次GC后)

 

-XX:+TraceClassLoading

打印类加载信息

 

 

 

-Xms 如:-Xms5m

最小堆内存

在Xms 和 Xmx配置相同的时候,初始化堆内存就是最大内存

在Xms 和 Xmx配置不相同的时候,JVM会尽可能维持最小堆内存,当内存不足的时候,会重新分配增加部分内存

 

Xmx 如:-Xmx10m

最大堆内存

-Xmn 如:-Xmn10m

设置年轻代大小

 

-XX:SurvivorRatio

Survivor(from和to)和eden的比例值

默认为8,survivor:eden=2:8 , from survivor占年轻代的1/10

-XX:NewRatio

年轻代和老年代的比值

默认值为4,表示年轻代:老年代=1:4,也就是说年轻代占堆 的1/5

方法区

-XX:PermSize

初始化空间

 

-XX:MaxPermSize

最大空间

 

-Xss

每个线程都有独立的栈空间,保存方法中的局部变量,参数等

本文标签
 {{tag}}
点了个评