JVM使用记录

JVM说明

Java虚拟机在运行Java程序的过程中,会把它管理的内存划分为几个不同的数据区域。

JDK1.6,1.7的JVM运行内存

线程私有的:程序计数器,虚拟机栈,本地方法栈

线程共享的:堆,方法区(永久代,持久代),直接内存(非运行时内存的一部分)

运行时内存

堆(Heap)内存 GC 堆(Garbage Collected Heap)。现在收集器基本都采用分代垃圾收集算法,分为新生代,老生代。用于存放对象实例,几乎所有的对象实例和数组都在这里分配内存

  • 新生代 PSYoungGen

    • eden space
    • from space
    • to space
  • 老生代 PSOldGen

    • object space

方法区 Method Area ,也叫非堆Non-Heap。存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据

  • 永久代 PSPermGen

    • object space

,线程私有的。生命周期随着线程的创建而创建,随着线程的死亡而死亡。 在 HotSpot 虚拟机中和 Java 虚拟机栈合二为一。

  • 程序计数器:字节码解释器通过这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等。唯一一个不会出现 OutOfMemoryError 的内存区域

  • 虚拟机栈栈内存 (Stack),其中栈就是现在说的虚拟机栈。实际上,Java 虚拟机栈是由一个个栈帧组成,而每个栈帧中都拥有:局部变量表、操作数栈、动态链接、方法出口信息。包括基本类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference 类型)。

  • 本地方法栈,虚拟机使用到的 Native 方法服务。本地方法栈也会创建一个栈帧,用于存放该本地方法的局部变量表、操作数栈、动态链接、出口信息。

JDK1.6的VM options配置

Java类:

public static void main(String[] args) {
     byte[] allocation1, allocation2,allocation3,allocation4,allocation5;
     allocation1 = new byte[32768*1024]; // 32768 = 32M
     allocation2 = new byte[1024*1024]; // 1024 = 1M
     allocation3 = new byte[1024*1024]; // 1024 = 1M
//   allocation4 = new byte[512*1024]; // OOM异常:Java heap space
//   allocation5 = new byte[1024*1024];
}

vm options配置

# 堆初始值50m,最大值50m,新生代内存:15m, 指定永久代内存大小:初始16m,最大64m
-Xms50m -Xmx50m -Xmn15m -XX:PermSize=16m -XX:MaxPermSize=64m -XX:+PrintCommandLineFlags -XX:+PrintGCDetails

输出信息:

-XX:InitialHeapSize=52428800 -XX:MaxHeapSize=52428800 -XX:MaxNewSize=15728640 -XX:NewSize=15728640 -XX:ParallelGCThreads=4 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC 
Heap
 PSYoungGen      total 13440K, used 3433K 
  eden space 11520K, 29% used 
  from space 1920K, 0% used 
  to   space 1920K, 0% used 
 PSOldGen        total 35840K, used 32768K 
  object space 35840K, 91% used 
 PSPermGen       total 21248K, used 3813K 
  object space 21248K, 17% used 

如果不指定 -Xmn 输出默认信息:

# 堆内存设置50m,各个区域内存占内存比例
-XX:InitialHeapSize=52428800 -XX:MaxHeapSize=52428800 
Heap
 PSYoungGen      total 14912K, used 3330K  占比 29%
  eden space 12800K, 26% used   占比 25%
  from space 2112K, 0% used     占比 4%
  to   space 2112K, 0% used     占比 4%
 PSOldGen        total 34176K, used 32768K  占比 66.75%
  object space 34176K, 95% used 
 PSPermGen       total 21248K, used 3703K   需要指定大小:默认20.75m 
  object space 21248K, 17% used 

运行时常量池分。

Class 文件中除了有类的版本、字段、方法、接口等描述信息外,还有常量池信息(用于存放编译期生成的各种字面量和符号引用)

既然运行时常量池时方法区的一部分,自然受到方法区内存的限制,当常量池无法再申请到内存时会抛出 OutOfMemoryError 异常。

JDK1.7 及之后版本的 JVM 已经将运行时常量池从方法区中移了出来,在 Java 堆(Heap)中开辟了一块区域存放运行时常量池。

JDK1.8的JVM运行内存

JDK1.8移出了方法区,改成了元空间(MetaSpace)。整个永久代有一个 JVM 本身设置固定大小上线,无法进行调整,而元空间使用的是直接内存,受本机可用内存的限制,并且永远不会得到 java.lang.OutOfMemoryError。你可以使用 -XX:MaxMetaspaceSize 标志设置最大元空间大小,默认值为 unlimited,这意味着它只受系统内存的限制。-XX:MetaspaceSize 调整标志定义元空间的初始大小如果未指定此标志,则 Metaspace 将根据运行时的应用程序需求动态地重新调整大小。默认容量 4496K=4.39m 已提交4864K = 4.75m, 预留1056768K = 1032m

一般MetaspaceSize默认5m,MaxMetaspaceSize默认1024m

JDK1.8的VM options配置

jdk1.8移除了-XX:PermSize=16m -XX:MaxPermSize=64m配置

vm options配置:

# 指定永久代内存大小
-Xms50m -Xmx50m  -XX:+PrintCommandLineFlags -XX:+PrintGCDetails

堆内存分配说明:

  • 堆内存共计50M = 新生代14.5m +老生代 33.5m +预留空间2m
  • 新生代PSYoungGen:14848K = 14.5m 占比 29%
    • eden space 12800K = 12.5m 占比25%
    • from space 2048K = 2m 占比4%
    • to space 2048K = 2m 占比4%
  • 老生代ParOldGen:34304K = 33.5m 占比 67%

GC信息如下:

-XX:InitialHeapSize=52428800 -XX:MaxHeapSize=52428800 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC 
Heap
 PSYoungGen      total 14848K, used 4736K 
  eden space 12800K, 37% used 
  from space 2048K, 0% used 
  to   space 2048K, 0% used 
 ParOldGen       total 34304K, used 32768K
  object space 34304K, 95% used 
 Metaspace       used 3450K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 376K, capacity 388K, committed 512K, reserved 1048576K
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=16m; support was removed in 8.0
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=64m; support was removed in 8.0
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 第二部分 自动内存管理机制 第二章 java内存异常与内存溢出异常 运行数据区域 程序计数器:当前线程所执行的字节...
    小明oh阅读 1,212评论 0 2
  • 这篇文章是我之前翻阅了不少的书籍以及从网络上收集的一些资料的整理,因此不免有一些不准确的地方,同时不同JDK版本的...
    高广超阅读 15,714评论 3 83
  • 内存溢出和内存泄漏的区别 内存溢出:out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,...
    Aimerwhy阅读 756评论 0 1
  • 1991年4月,由James Gosling主导的团队创造了Oak语言,java的前身,1995年5月23号,Oa...
    Java架构阅读 1,609评论 1 37
  • Java8张图 11、字符串不变性 12、equals()方法、hashCode()方法的区别 13、...
    Miley_MOJIE阅读 3,731评论 0 11