问题背景

Java虚拟机JVM简介与自己的一些理解,只写一篇太长了,分开小片段,慢慢消化

JVM整体架构

1 JVM 内存共分为虚拟机栈、堆、方法区、程序计数器、本地方法栈五个部分

名称特征作用配置参数异常
程序计数器占用内存小,线程私有,生命周期与线程相同大致为字节码行号指示器
虚拟机栈线程私有,生命周期与线程相同,使用连续的内存空间Java 方法执行的内存模型,存储局部变量表、操作栈、动态链接、方法出口等信息-XssStackOverflowError/OutOfMemoryError
线程共享,生命周期与虚拟机相同,可以不使用连续的内存地址保存对象实例,所有对象实例(包括数组)都要在堆上分配-Xms
-Xsx
-Xmn
OutOfMemoryError
方法区线程共享,生命周期与虚拟机相同,可以不使用连续的内存地址存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据-XX:PermSize=16M
-XX:MaxPermSize=64M
-XX:MetaspaceSize=16M
-XX:MaxMetaspaceSize=64M   
OutOfMemoryError
本地方法栈线程私有为虚拟机使用到的 Native 方法服务StackOverflowError/OutOfMemoryError

2 JVM分为五大模块: 类装载器子系统、运行时数据区、执行引擎、本地方法接口和垃圾收集模块

JVM运行时内存

1 Java 虚拟机有自动内存管理机制,如果出现面的问题,排查错误就必须要了解虚拟机是怎样使用内存的

2 Java7和Java8内存结构的不同主要体现在方法区的实现

  • 方法区是java虚拟机规范中定义的一种概念上的区域,不同的厂商可以对虚拟机进行不同的实现。

  • 通常使用的Java SE都是由Sun JDK和OpenJDK所提供,这也是应用最广泛的版本。而该版本使用的VM就是HotSpot VM。通常情况下,所讲的java虚拟机指的就是HotSpot的版

  • 针对JDK8虚拟机内存详解

    3 JDK7和JDK8变化小结

线程私有的:

  • 程序计数器
  • 虚拟机栈
  • 本地方法栈

线程共享的:

  • 方法区

直接内存(非运行时数据区的一部分)

4 对于Java8,HotSpots取消了永久代,那么是不是就没有方法区了呢?

  • 当然不是,方法区只是一个规范,只不过它的实现变了。
  • 在Java8中,元空间(Metaspace)登上舞台,方法区存在于元空间(Metaspace)。同时,元空间不再与堆连续,而且是存在于本地内存(Native memory)

5 方法区Java8之后的变化

  • 移除了永久代(PermGen),替换为元空间(Metaspace)
  • 永久代中的class metadata(类元信息)转移到了native memory(本地内存,而不是虚拟机)
  • 永久代中的interned Strings(字符串常量池) 和 class static variables(类静态变量)转移到了Java heap
  • 永久代参数(PermSize MaxPermSize)-> 元空间参数(MetaspaceSize MaxMetaspaceSize)

6 Java8为什么要将永久代替换成Metaspace

  • 字符串存在永久代中,容易出现性能问题和内存溢出
  • 类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难,太小容易出现永久代溢出,太
    大则容易导致老年代溢出
  • 永久代会为 GC 带来不必要的复杂度,并且回收效率偏低
  • Oracle 可能会将HotSpot 与 JRockit 合二为一,JRockit没有所谓的永久代




作为程序员第 223 篇文章,每次写一句歌词记录一下,看看人生有几首歌的时间,wahahaha …

Lyric: 脑海里 你的笑容太彻底

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐