jdk1.8以前的jvm的内存结构图(有方法区的概念):

以上这个图可以看出内存结构的构成:

  1. 方法区
  2. 虚拟机栈
  3. 程序计数器
  4. 本地方法栈
  5. 直接内存

下面开始详细介绍这些内容;

jdk1.8以后的jvm的内存结构图(引入了元空间概念),下面有具体的讲解。

1. 方法区(线程共享)

1.1 定义:

  被所有线程共享的一块内存区域。

  用于存储已被虚拟机加载的类信息,常量,静态变量等。

  这个区域的内存回收目标主要针对常量池的回收和对类型的卸载。

  当方法区无法满足内存分配需求时,则抛出OutOfMemoryError异常。

  JDK1.7中,已经把放在永久代的字符串常量池移到堆中。

  JDK1.8撤销永久代,引入元空间。

1.2 组成

jdk 1.8 后有元空间的概念,方法区不再占用jvm内存,占用本地内存。

1.3 方法区内存溢出

1.8 以前会导致永久代内存溢出

永久代内存溢出 java.lang.OutOfMemoryError: PermGen space

修改永久代内存命令 -XX:MaxPermSize=8m

1.8 之后会导致元空间内存溢出

元空间内存溢出 java.lang.OutOfMemoryError: Metaspace

修改元空间内存命令 -XX:MaxMetaspaceSize=8m

场景:Spring,Mybatis 底层都用到了动态代理,动态生成类的字节码。

1.4 运行时常量池

常量池,就是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量 等信息

运行时常量池,常量池是 *.class 文件中的,当该类被加载,它的常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址(字符串在运行时,用到了才会存到堆中的StringTable中--相当于懒加载,串池中值是唯一的)

反编译class 命令:Javap –v HelloWord.class

1.5 练习了解StringTable

先看几道题:

String s1 = "a";

String s2 = "b";

String s3 = "a" + "b";  //javac 在编译期间的优化(常量不可能再变),结果已经在编译期确定为ab

s4 //new StringBuilder.append(“a”).append(“b”).toString()   new String(“ab”)

s4 //是新对象,在堆中。常量在常量池中

String s4 = s1 + s2;

String s5 = "ab";

String s6 = s4.intern();

问题如下:

System.out.println(s3==s4);//false

System.out.println(s3==s5);//ture

System.out.println(s3==s6);//ture

String x2 = new String("c") + new String("d");

String x1 = "cd";

x2.intern();

// 问题如下:

System.out.println(x1 == x2);  //jdk1.6 //false

System.out.println(x1 == x2);  //jdk1.8 //ture

1.6 StringTable 特性

1.常量池中的字符串仅是符号,第一次用到时才变为对象

2.利用串池的机制,来避免重复创建字符串对象

3.字符串变量拼接的原理是 StringBuilder (1.8)

4.字符串常量拼接的原理是编译期优化

5.可以使用 intern 方法,主动将串池中还没有的字符串对象放入串池

jdk1.8 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有则放入串池,会把串池中的对象返回

jdk1.6 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有会把此对象复制一份,放入串池, 会把串池中的对象返回

1.7 StringTable 位置

StringTable本质也就是常量池,以前存在于方法区中,jdk1.7以后就进行了修改。放到了堆中,因为字符串比较多,垃圾回收能够及时清理多余的数据。

1.8 StringTable 垃圾回收

-XX:+PrintStringTableStatistics查看字符串参数的大小信息

-XX:+PrintGCDetails -verbose:gc 垃圾回收的详细信息(次数,时间。。。)

1.9 StringTable 性能调优

调整 -XX:StringTableSize=桶个数,桶数越多会越快(减少了比对的情节)

考虑将字符串对象是否入池(string.intern())

2. 

2.1 定义:

Heap 堆

通过 new 关键字,创建对象都会使用堆内存

特点:1.它是线程共享的,堆中对象都需要考虑线程安全的题

2.有垃圾回收机制

2.2 堆内存溢出

堆内存溢出报错:java.lang.OutOfMemoryError

堆内存默认大小是4g,修改堆内存大小命令:-Xmx256m

2.3 堆内存诊断

1. jps 工具

查看当前系统中有哪些 java 进程

2. jmap 工具

查看堆内存占用情况命令:jmap - heap 进程id

3. jconsole 工具

图形界面的,多功能的监测工具,可以连续监测

案例

垃圾回收后,内存占用仍然很高,定位问题:jvisualvm

3. 虚拟机栈

3.1 定义

Java Virtual Machine Stacks (Java 虚拟机栈)

每个线程运行时所需要的内存,称为虚拟机栈

每个栈由多个栈帧(Frame)组成,对应着每次方法调用时所占用的内存

每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法

问题辨析

  1. 垃圾回收是否涉及栈内存?  不涉及,运行后会自动弹出
  2. 栈内存分配越大越好吗?   不是,内存一定,栈内存分配的大,线程数就会变少
  3. 方法内的局部变量是否线程安全?  普通变量是安全的。静态变量是共享的不安全。

如果方法内局部变量没有逃离方法的作用访问,它是线程安全的

如果是局部变量引用了对象,并逃离方法的作用范围,需要考虑线程安全

3.2 栈内存溢出

栈帧过多导致栈内存出(递归)

栈帧过大导致栈内存出--基本上不会出现

栈内存默认大小是1M,修改栈内存大小 -Xss256k

3.3 线程运行诊断

案例1: cpu 占用过多

定位:1.用top定位哪个进程对cpu的占用过高

2.ps H -eo pid,tid,%cpu | grep 进程id (用ps命令进一步定位是哪个线程引起的cpu占用过高,线程需要转成16进制配合jstack)

3.jstack 进程id,可以根据线程id 找到有问题的线程,进一步定位到问题代码的源码行号

4.程序计数器

4.1 定义

Program Counter Register 程序计数器(寄存器)

作用,是记住下一条jvm指令的执行地址(有时间片的概念,在一定时间内还没运行完就会暂时释放线程)

特点:1.是线程私有的  2.不会存在内存溢

4.2 作用

0:

getstatic

#20

// PrintStream out = System.out;

3:

astore_1

// --

4:

aload_1

// out.println(1);

5:

iconst_1

// --

6:

invokevirtual #26

// --

9:

aload_1

// out.println(2);

10:

iconst_2

// --

11:

invokevirtual #26

// --

14:

aload_1

// out.println(3);

15:

iconst_3

// --

16:

invokevirtual #26

// --

19:

aload_1

// out.println(4);

20:

iconst_4

// --

21:

invokevirtual #26

// --

24:

aload_1

// out.println(5);

25:

iconst_5

// --

26:

invokevirtual #26

// --

29:

return

5.本地方法栈

本地方法:不是用Java语言编写的方法,因为Java语言是有一定限制的,有些情况下它是不能直接和操作系统打交道。这时就需要调用一些用C或C++编写的方法去跟操作系统底层打交道。Java语言可以调用这些本地方法间接的调用操作系统底层的一些功能。

本地方法栈:本地方法运行时所需要的内存就是本地方法栈。

6.直接内存

6.1 定义

直接内存Direct Memory

常见于 NIO 操作时,用于数据缓冲区

分配回收成本较高,但读写性能高

不受 JVM 内存回收管理 System.gc();

6.2 分配和回收原理

使用了 Unsafe 对象完成直接内存的分配回收,并且回收需要主动调用 freeMemory 方法

ByteBuffer 的实现类内部,使用了 Cleaner (虚引用)来监测 ByteBuffer 对象,一旦 ByteBuffer 对象被垃圾回收,那么就会由 ReferenceHandler 线程通过 Cleaner 的 clean 方法调 用 freeMemory 来释放直接内存

jvm讲解-jvm内存结构详解相关推荐

  1. JVM之内存结构详解

    对于开发人员来说,如果不了解Java的JVM,那真的是很难写得一手好代码,很难查得一手好bug.同时,JVM也是面试环节的中重灾区.今天开始,<JVM详解>系列开启,带大家深入了解JVM相 ...

  2. jvm之java内存区域详解篇guide哥yyds

    jvm 一.java内存区域详解 1.运行时数据区域 线程私有的: 虚拟机栈 本地方法栈 程序计数器 线程共享的: 堆 方法区 直接内存(非程序运行时数据区的一部分) 1.1什么是程序计数器 程序计数 ...

  3. JVM总结之内存区域详解

    一.概述 1 运行时数据区概述 Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域.JDK 1.8 和之前的版本略有不同,下面会介绍到. 线程私有的: 程序计数器 ...

  4. [精]Oracle 内存结构详解

    内存结构 现代计算机中,CPU 对内存的访问速度要比从磁盘的速度快千倍,因此 Oracle 对于数据的访问 也尽量都在内存中完成,而不是直接修改硬盘上的数据.内存内容在合适的时候再同步到磁盘. Ora ...

  5. JVM 运行时内存空间详解——元空间

    通过上一篇文章,我们大体了解了JVM的整体架构,其分为:元数据(JDK7是方法区).堆.虚拟机栈.本地方法栈.程序计数器几个部分. 本篇文章,咱们对元空间进行剖析,一探究竟. 1. 元空间介绍 在JD ...

  6. jvm堆外内存排查详解

    文章目录 前言 一.堆外内存排查 1.背景 2.内存对比 3.堆外内存检查 4.排查堆外内存 5.glibc内存泄露 结尾 前言 内存泄漏想必大家并不陌生,对于jvm的内存泄漏,有很多排查手段和方便的 ...

  7. 【JVM】Java内存区域详解(通俗易懂系列)

    Java虚拟机拥有管理内存的权利. 一.运行时数据区 在Java程序执行的过程中,Java虚拟机会将它管理的内存分为若干个不同数据区域(JDK1.8与之前版本不同) 线程私有: 虚拟机栈 本地方法栈 ...

  8. Oracle内存结构详解(三)--管理Oracle Share Pool

    SGA中的共享池由库缓存(Library Cache).字典缓存(Dictionary Cache).用于并行执行消息的缓冲以及控制结构组成. Shared Pool的大小由参数SHARED_POOL ...

  9. [java] 虚拟机(JVM)底层结构详解[转]

    [java] 虚拟机(JVM)底层结构详解[转] 本文来自:曹胜欢博客专栏.转载请注明出处:http://blog.csdn.net/csh624366188 在以前的博客里面,我们介绍了在java领 ...

  10. JVM(Java虚拟机)详解(JVM 内存模型、堆、GC、直接内存、性能调优)

    JVM(Java虚拟机) JVM 内存模型 结构图 jdk1.8 结构图(极简) jdk1.8 结构图(简单) JVM(Java虚拟机): 是一个抽象的计算模型. 如同一台真实的机器,它有自己的指令集 ...

最新文章

  1. c# 一些控件常用屬性
  2. java并发编程——并发容器类介绍
  3. RobotFramework自动化框架—数据驱动测试
  4. POJ2528的另一种解法(线段切割)
  5. 经典|图解Linux内存性能优化核心思想
  6. java中字符串的操作_java中字符串的操作
  7. web项目的创建和发布
  8. VS2015 Cordova Ionic移动开发(五)
  9. ISA Server 2006 部署步骤
  10. 面试中,答不出产品方法论?4个方法教给你...
  11. Kinaba及X-Pack插件安装
  12. 服务器2003系统U盘安装方法,u盘winpe下安装windows server 2003详细教程
  13. 《高等数学》:推导第七版下册第十章第四节的“利用曲面的参数方程求曲面的面积“
  14. 171108 将Youtube自动翻译字幕转换成srt文件本地播放
  15. STM32的USART3(PC10,PC11)异常,USART3_TX(PC10)持续低电平(0V)
  16. 四川江安戏剧“青年训练营”:播撒颗颗戏剧种子
  17. 把撒哈拉沙漠变成一个太阳能农场,这可能吗?
  18. 微信windows版_微信多开教程:Win、Mac、iOS、Android
  19. 百度地图标注点+搜索
  20. 解决Google Colab 读取Google Drive(云盘) 文件速度慢

热门文章

  1. python制作动态的微信个人名片
  2. 斐讯K2刷华硕固件+全套工具
  3. 一步一步搭建11gR2 rac+dg之配置单实例的DG(八)
  4. 2018考研信工所二室
  5. g729源码分析-开篇
  6. 学习Java8这一篇就够了
  7. xp无线网卡开启的服务器,无线网卡在 Windows XP 系统下的安装与使用过程
  8. JavaWeb 学习路线
  9. Amlogic S905X3外设驱动之RTC驱动:HYM8563驱动
  10. 高分1、2号卫星原始遥感影像数据