`
fly_ever
  • 浏览: 149940 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java虚拟机内存结构

    博客分类:
  • java
阅读更多

Java虚拟机的内存结构

 

      在程序运行时,JVM包含了两种运行时数据区,一种是与JVM同步存在的,在JVM启动时一直存在,直到JVM退出时才销毁,由所有的线程共享;另一种是与每个线程同步存在,线程退出则销毁。


 

运行时数据区包含如下几部分:

1, 程序计数器
       每一个Java线程都有一个PC寄存器,用以记录在线程切换回来后恢复到正确的执行位置。

       如该线程正在执行一个Java方法,则计数器记录的是正在执行的虚拟机字节码地址,如执行native方法,则计数器值为undefined

      因为只是记录线程执行时的返回地址,因此内存是足够使用的,该区域也是唯一一个在JVM中没有规定任何OutOfMemoryError情况的区域。

2,JVM栈

      每个线程保持一个JVM私有栈,与线程一起创建,保存栈帧,栈帧用来存储局部变量,中间结果,以及方法返回值等。

      该区域会抛出如下异常:

  • If the computation in a thread requires a larger Java virtual machine stack than is permitted, the Java virtual machine throws a StackOverflowError.
  • If Java virtual machine stacks can be dynamically expanded, and expansion is attempted but insufficient memory can be made available to effect the expansion, or if insufficient memory can be made available to create the initial Java virtual machine stack for a new thread, the Java virtual machine throws an OutOfMemoryError.

3,堆

       堆空间是JVM中所有的线程共享的区域,在虚拟机启动时创建,堆空间不需要是连续的。用于存储所有的对象实例和数组。是垃圾收集管理的主要区域。

       该区域会抛出如下异常:

     The following exceptional condition is associated with the heap:

  • If a computation requires more heap than can be made available by the automatic storage management system, the Java virtual machine throws an OutOfMemoryError.

4,方法区:

       方法区是JVM中所有线程共享的区域,在虚拟机启动时创建,堆空间不需要是连续的。用于存储已加载的每个class的信息,比如运行时的常量池,字段和方法数据,方法的代码等。

       方法区是堆的逻辑组成部分,但可以选择不对这个区域进行垃圾收集。方法区并不等同于永久代,但在虚拟机HotSpot实现时,方法区是在永久代中(JDK1.6及以下版本)。

       该区域会抛出如下异常:

The following exceptional condition is associated with the method area: 

  • If memory in the method area cannot be made available to satisfy an allocation request, the Java virtual machine throws an OutOfMemoryError.

5,运行时常量池:

       运行时常量池是从方法区中分配出来的,在每一个类或者接口创建时,由JVM创建一个对应的常量池,用于存放各种常量数据,从编译时生成的各种字符数字到运行时需要用到的各种字段和方法引用。运行时常量池可以理解为是类或接口的常量池的运行时表现形式。

       该区域会抛出如下异常:

The following exceptional condition is associated with the construction of the runtime constant pool for a class or interface: 

  • When creating a class or interface, if the construction of the runtime constant pool requires more memory than can be made available in the method area of the Java virtual machine, the Java virtual machine throws an OutOfMemoryError.

6,本地方法栈

        Native Method Stacks 用来支持Native 方法,即不是使用Java语言写的方法。每个线程创建时,分配一个本地方法栈,

       该区域会抛出如下异常:

 The following exceptional conditions are associated with native method stacks:

 

  • If the computation in a thread requires a larger native method stack than is permitted, the Java virtual machine throws a StackOverflowError
  • If native method stacks can be dynamically expanded and native method stack expansion is attempted but insufficient memory can be made available, or if insufficient memory can be made available to create the initial native method stack for a new thread, the Java virtual machine throws an OutOfMemoryError.

JVM实现(HotSpot)的版本区别:

 

      JDK1.7中,方法区已经转移到了堆中,运行时常量池也从堆空间中分配。

      从JDK8开始,永久代(PermGen)的概念被废弃掉了,取而代之的是一个称为Metaspace的存储空间。Metaspace使用的是本地内存,而不是堆内存,也就是说在默认情况下Metaspace的大小只与本地内存大小有关。

 

JVM内存管理相关参数:

     1,标准参数:功能和输出的参数都是很稳定的 在未来的JVM版本中不会改变 可以使用java -help检索出所有的标准参数。

      2,X参数:非标准化参数 在未来的版本可能会改变 所有的参数都用-X开始 可以使用java -X检索 但是注意没有-Xcomp。

      3,XX参数:非标准 很长一段时间不会列出来 用于JVM开发的debug和调优。

      -XX:+<option> 启用option
      -XX:-<option> 不启用option
      -XX:<option>=<number> 设定option的值为数字类型,可跟单位,例如 32k, 1024m, 2g
      -XX:<option>=<string> 设定option的值为字符串,例如-XX:HeapDumpPath=./dump.core

 

      -Xms<size> 设置初始Java堆的大小。

      -Xmx<size> 设置最大Java堆的大小。

      -Xss<size>  设置Java线程堆栈大小。

      -Xmn<size> 设置年轻代大小。

 

       -XX:-DisableExplicitGC   -XX:+DisableExplicitGC: 禁用显式垃圾收集, JVM任会在必要时执行垃圾收集。

        -XX:+UseGCOverheadLimit  限制GC的运行时间,GC运行过长,则抛出OOM错误。

       -XX:-UseParallelGC  新生代使用并行清除的垃圾收集器

       -XX:-UseParallelOldGC 老年代和新生代都使用并行清除的垃圾收集器

       -XX:-UseSerialGC  使用串行垃圾收集器

       -XX:+UseG1GC  使用G1垃圾收集器

       -XX: +UseConcMarkSweepGC   使用CMS垃圾收集器。

       -XX:MaxGCPauseMillis=n   设置垃圾收集最大暂停时间

       -XX:InitiatingHeapOccupancyPercent=n  设置触发垃圾收集的堆内存占用比,默认为45,如设置为0,则会一直不停的垃圾收集

       -XX:NewRatio=n   老年代/新生代占用比值, 默认值为2,即新生代占用整个内存的1/3,老年代占用2/3.

       -XX:NewSize=2m  新生代空间大小

       -XX:SurvivorRatio=n  Edon/Survivor 占用比值,默认值为8,新生代包含一个Edon区和2个Survivor区,默认值8,则代表一个Survivor区占用整个新生代的1/10

       -XX:TargetSurvivorRatio=50  GC后,期望的Survivor区空间的占比

       -XX:MaxTenuringThreshold=n 垃圾最大年龄,默认值为15

       -XX:ParallelGCThreads=n  并行收集时的线程数,可配置为与处理器个数相同

       -XX:ConcGCThreads=n 并行收集时的线程数,可配置为与处理器个数相同

       -XX:G1ReservePercent=n  使用G1收集器时,设置保留堆的大小百分比,默认值为10

       -XX:G1HeapRegionSize=n  设置Java堆被分割的区域大小,数值范围从1M到32M

 

       -XX:LargePageSizeInBytes=4m 设置堆的内存页大小

       -XX:MaxHeapFreeRatio=70  GC后,空余堆的大小占比值超过该比值,则缩小堆内存预估值。

       -XX:MinHeapFreeRatio=40  GC后,空余堆的大小占比值小于该比值,则扩大堆内存预估值。

       -XX:MaxNewSize=size  新生代占用的内存最大值

       -XX:MaxPermSize=64m  永久代占用的内存最大值

 

       -XX:HeapDumpPath=./java_pid<pid>.hprof  堆内存快照的存储路径

       -XX:-HeapDumpOnOutOfMemoryError   当发生OOM错误时,输出一个堆内存快照文件

       -XX:OnError="<cmd args>;<cmd args>"   当发生错误时,执行一个指令集,该指令集是与OS相关的,在Linux下是bash脚本,windows下是dos命令集。

       -XX:OnOutOfMemoryError="<cmd args>; <cmd args>" 当发生OOM错误时,执行一个指令集,该指令集是与OS相关的,在Linux下是bash脚本,windows下是dos命令集。

 

        -XX:-PrintGC  开启GC日志打印

        -XX:-PrintGCDetails  打印GC时的详细信息

        -XX:-PrintGCTimeStamps   打印GC操作时的时间戳

        -XX:-PrintTenuringDistribution  打印对象的存活周期信息

 

        -XX:+UseCompressedOops   在64位的机器上,压缩使用32位的类指针,以节约内存空间,适用于Java堆的大小不到32G时。

        -XX:InitialTenuringThreshold=7   设置初始对象在新生代中最大存活次数

        -XX:MaxTenuringThreshold=n   设置对象在新生代中最大存活次数

        -XX:NumberOfGClogFiles=1  设置切分GC日志文件的数量,值>=1, 命名格式  filename.1, filename.2..... filename.n-1.

        -XX:GCLogFileSize=8K   设置切分GC日志的大小,值>=8k.

 

 内存的设置该怎么设置呢?设置成多大比较合适,既不浪费内存,又不影响性能呢?

依据的原则是根据Java Performance里面的推荐公式来进行设置。

 

具体来讲:

Java整个堆大小设置,Xmx 和 Xms设置为老年代存活对象的3-4倍,即FullGC之后的老年代内存占用的3-4倍

永久代 PermSize和MaxPermSize设置为老年代存活对象的1.2-1.5倍。

年轻代Xmn的设置为老年代存活对象的1-1.5倍。

老年代的内存大小设置为老年代存活对象的2-3倍。

 

Sun官方建议年轻代的大小为整个堆的3/8左右

堆大小=年轻代大小+年老代大小, 即xmx=xmn+老年代大小 。 Permsize不影响堆大小。

 

如何确认老年代存活对象大小?

JVM参数中添加GC日志,GC日志中会记录每次FullGC之后各代的内存大小,观察老年代GC之后的空间大小。可观察一段时间内(比如2天)的FullGC之后的内存情况,根据多次的FullGC之后的老年代的空间大小数据来预估FullGC之后老年代的存活对象大小(可根据多次FullGC之后的内存大小取平均值)

 

 

 

参考资料:

 https://docs.oracle.com/javase/specs/jvms/se6/html/VMSpecTOC.doc.html

 http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

 

 

 

 

 

 

    

  • 大小: 40 KB
  • 大小: 22.8 KB
0
0
分享到:
评论

相关推荐

    java虚拟机的内存结构

    java虚拟机的内存结构,关于内存的相关介绍等,想要了解更多JVM的

    Android面试(一)Java虚拟机内存结构分析

    1、Java虚拟机内存结构模型 Java虚拟机内存结构分:JVM堆、方法区、虚拟机栈、本地方法栈、程序计数器。 JVM堆:所有线程共享的运行时内存区域,是GC回收的主场所,Java堆保存Java的实例对象,从内存回收对象的存活...

    2_Java虚拟机( 内存结构).pdf

    Java虚拟机( 内存结构),可以深入了解JVM虚拟机的内存结构,对于Java虚拟机需要有深入了解的人员可以下载。

    java虚拟机规范(java SE7)

    第二章:java虚拟结构(运行时区域内存:寄存器,java虚拟机栈,java堆,方法去,运行时常量池,本地方法栈); 第三章:为java虚拟机编译; 第四章:Class文件格式; 第五章:加载、链接与初始化

    Java虚拟机(内存结构)1

    Java虚拟机(内存结构)1

    Java虚拟机内存区域模型

    JVM,虚拟机结构,java,内存结构

    Java虚拟机 JVM 内存结构介绍

    描述Java虚拟机规范中关于内存管理的部分 主要介绍Runtime Data Area,包括Java Stack,Native Method Stack, Program Counter Register,Method Area以及Heap 还简要介绍了Runtime Data Area周边的模块,包括Class...

    JAVA虚拟机精讲

    《Java虚拟机精讲》以极其精练的语句诠释了HotSpot VM 的方方面面,比如:字节码的编译原理、字节码的内部组成结构、通过源码的方式剖析HotSpot VM 的启动过程和初始化过程、Java 虚拟机的运行时内存、垃圾收集算法...

    JAVA虚拟机全面理解.docx

    其中基础结构层包括Java虚拟机的所有基本功能,如内存管理、线程管理、类加载机制等;执行引擎层则负责解释Java字节码并执行;应用层则提供了与具体应用相关的功能,如安全管理器、垃圾收集器等。

    Java虚拟机内存优化实践

    前面一篇文章介绍了Java虚拟机的体系结构和内存模型,既然提到内存,不得不说到内存泄露。众所周知,Java是从C++的基础上发展而来的,而C++程序的很大的一个问题是内存泄露难以解决,尽管Java的JVM有一套自己的垃圾...

    Java虚拟机精讲.高翔龙.带书签完整版.pdf

    本书以极其精练的语句诠释了HotSpot VM 的方方面面,比如:字节码的编译原理、字节码的内部组成结构、通过源码的方式剖析HotSpot VM 的启动过程和初始化过程、Java 虚拟机的运行时内存、垃圾收集算法、垃圾收集器...

    Java 虚拟机学习笔记:Java 内存区域,垃圾收集,内存分配与回收策略,JVM 调优,文件结构,类加载机制,Java 程序

    它采用了“一次编写,到处运行”的原则,即一次编写的程序可以在不同的操作系统上运行,这得益于Java虚拟机(JVM)的存在。JVM是Java的核心组成部分,它可以将Java代码解释成特定平台上的机器码,从而实现跨平台运行...

    深入理解Java虚拟机精华知识点

    Java虚拟机有如下几个主要特点:首先,它的结构严谨,面向对象,能够摆脱硬件平台的束缚,实现了“一次编写,到处运行”的理想;其次,它提供了一个相对安全的内存管理和访问机制,避免了绝大部分的内存泄漏和指针...

    java虚拟机知识点整理

    自己看书整理的 java虚拟机精品知识点 java内存区域与内存溢出处理 虚拟机栈和本地方法栈区别 对象定位访问 垃圾收集器GC管理 虚拟机GC垃圾回收收集算法(内存回收方法论) 虚拟机GC垃圾回收收集器(内存回收具体实现...

    Java虚拟机的基本结构 (2)1

    Java虚拟机的基本结构 类加载子系统类加载子系统Java堆Java堆 类加载子系统类加载子系统Java堆Java堆 本地方法栈本地方法栈直接内存直接内存Jav

    Java高级面试JVM虚拟机、内存结构、垃圾回收机制

    java工程师高级面试之JVM虚拟机底层原理篇:VM种类,内存结构,运行原理,垃圾回收算法,各种垃圾回收器等。

    深入理解Java虚拟机视频教程(jvm性能调优+内存模型+虚拟机原理)视频教程

    第23节Java内存区域-Java虚拟机栈00:12:04分钟 | 第24节Java内存区域-程序计数器00:12:54分钟 | 第25节Java内存区域-本地方法栈00:02:39分钟 | 第26节Java内存区域-堆内存00:05:08分钟 | 第27节Java内存区域-...

    浅谈Java的虚拟机结构以及虚拟机内存的优化

    主要介绍了Java的虚拟机结构以及虚拟机内存的优化,讲到了JVM的堆和栈空间及GC垃圾回收等重要知识,需要的朋友可以参考下

    JAVA虚拟机精讲 pdf

    本书以极其精练的语句诠释了HotSpot VM 的方方面面,比如:字节码的编译原理、字节码的内部组成结构、通过源码的方式剖析HotSpot VM 的启动过程和初始化过程、Java 虚拟机的运行时内存、垃圾收集算法、垃圾收集器...

Global site tag (gtag.js) - Google Analytics