2、JVM的内存
1、JVM中的内存结构
从OS的角度来看,JVM运行时会把一部分内存虚拟机化,所以把内存分为直接内存(未被虚拟机化的内存)和运行时数据区(被虚拟机化的内存)
JVM的运行时数据区若从线程的角度来看,可分为线程共享的区域和线程私有的区域
线程共享区主要由方法区、堆组成,其中方法区还会划分出一部分作为运行时常量池
线程私有去区主是由一条条线程的私有内存组成的,每一条线程的私有区域是由虚拟机栈、本地方法栈以及程序计数器来构成的
2、运行时数据区中的线程私有区域
(1)虚拟机栈
一条线程可以执行多个方法,每一个方法在执行时所需要的数据、指令 、返回地址都会存储在虚拟机栈中,每一个方法都会打包成一个栈帧
每一个栈帧都是由局部变量表、操作数据栈、动态连接以及完成出口组成
当线程执行的方法中有调用别的方法时,会把每一个方法包装到一个栈帧中,将栈帧压到虚拟机栈中,后入栈的方法先出栈执行,从而实现方法中的调用逻辑
1、栈帧中的局部变量表:长度为32位,用来存放方法中的变量,包括Java中的8大基础数据类型,局部对象的引用
2、栈帧中的操作数据栈:存放 java 方法执行的操作数的,它就是一个栈,先进后出的栈结构,操作数栈,就是用来操作的,操作的的元素可以是任意的 java 数据类型,所
3、栈帧中的动态连接:一个方法调用了另外的其他方法时,就是通过常量池中指向方法的符号引用来表示的,动态连接会将这些符号引用转化为调用方法的直接引用
4、栈帧中的完成出口:正常返回(调用程序计数器中的地址作为返回)、异常的话(通过异常处理器表<非栈帧中的>来确定)
方法执行完成步骤:1)恢复局部变量表和操作数栈
2)把返回值压入调用方法的栈帧的操作数栈中
3)调用程序计数器指向方法调用的下一条指令
异常的话:(通过异常处理表<非栈帧中的>来确定)
5、当要执行的方法过多或方法执行的所需要的资源过大时,会造成栈的溢出(OOM)
(2)本地方法栈
本地方法栈的功能与虚拟机栈的功能类似,虚拟机栈用来管理程序中函数的调用,而本地方法栈服务于native方法,用来调用C语言编写的本地方法
(3)程序计数器
占据较小的内存空间,主要用来记录各个线程执行的字节码的地址,作为当前线程执行的字节码的行号指示器;各线程之间独立存储,互不影响。
程序技术器也是JVM中唯一不会发生OOM(内存溢出)的内存区域
3、运行时数据区中的线程共享区域
(1)方法区
位于线程共享区,其中存储了的每一个类的结构信息(运行时常量池、字段、方法数据、构造函数、普通方法的字节码内容等等)
JDK1.7中,通常会将方法区称为永久代,永久代的静态变量和运行时常量池转移到了堆中,其余部分则存储在 JVM 的非堆内存中
JDK1.8之后,用元空间替换了永久代,存储位置是本地内存
不管常量池存储在哪,逻辑上属于方法区
Java8 为什么使用元空间替代永久代?
移除永久代是为了融合 HotSpot JVM 与 JRockit VM 而做出的努力,因为 JRockit 没有永久代,所以不需要配置永久代。
永久代内存经常不够用或发生内存溢出,抛出异常 java.lang.OutOfMemoryError: PermGen。这是因为在 JDK1.7 版本中,指定的 PermGen 区大小为8M,由于 PermGen 中类的元数据信息在每次 FullGC 的时候都可能被收集,回收率都偏低,成绩很难令人满意;还有为 PermGen 分配多大的空间很难确定,PermSize 的大小依赖于很多因素,比如,JVM 加载的 class 总数、常量池的大小和方法的大小等。

2、JVM的内存的更多相关文章
- jvm的内存分配总结
最近看了周志明版本的<深入理解Java虚拟机>第一版和第二版,写的很好,收获很多,此处总结一下. jvm中内存划分: 如上图,一共分为五块,其中: 线程共享区域为: 1.java堆 ...
- java语言:Linux与JVM的内存关系分
在一些物理内存为8g的服务器上,主要运行一个Java服务,系统内存分配如下:Java服务的JVM堆大小设置为6g,一个监控进程占用大约 600m,Linux自身使用大约800m.从表面上,物理内存应该 ...
- 【转】JVM 堆内存设置原理
堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定 ...
- JVM的内存区域划分
JVM的内存区域划分 学过C语言的朋友都知道C编译器在划分内存区域的时候经常将管理的区域划分为数据段和代码段,数据段包括堆.栈以及静态数据区.那么在Java语言当中,内存又是如何划分的 ...
- 转: 关于Linux与JVM的内存关系分析
转自: http://tech.meituan.com/linux-jvm-memory.html Linux与JVM的内存关系分析 葛吒2014-08-29 10:00 引言 在一些物理内存为8g的 ...
- 设置TOMCAT的JVM虚拟机内存大小
你知道如何设置TOMCAT的JVM虚拟机内存大小吗,这里和大家分享一下,JAVA程序启动时JVM都会分配一个初始内存和最大内存给这个应用程序.这个初始内存和最大内存在一定程度都会影响程序的性能. 设置 ...
- 解决JVM最大内存设置问题
这里和大家讨论一下如何获得JVM最大内存,在命令行下用java-XmxXXXXM-version命令来进行测试,然后逐渐的增大XXXX的值,如果执行正常就表示指定的内存大小可用,否则会打印错误信息. ...
- 图解JVM在内存中申请对象及垃圾回收流程
http://longdick.iteye.com/blog/468368 先看一下JVM的内存模型: 从大的方面来讲,JVM的内存模型分为两大块: 永久区内存( Permanent space )和 ...
- Linux与JVM的内存关系分析
引言 在一些物理内存为8g的server上,主要执行一个Java服务,系统内存分配例如以下:Java服务的JVM堆大小设置为6g,一个监控进程占用大约600m,Linux自身使用大约800m. 从表面 ...
- jvm的内存管理【转】
[转]JVM内存管理 这些日子一直在研究jvm内存管理的东西,网上的知识很多,总结一下,能沉淀下来的就是自己的! 首先,刚学java的时候就知道java类文件是以 .java为后缀的文件,经过java ...
随机推荐
- 初识ABP vNext(6):vue+ABP实现国际化
Tips:本篇已加入系列文章阅读目录,可点击查看更多相关文章. 目录 前言 开始 语言选项 语言切换 注意 最后 前言 上一篇介绍了ABP扩展实体,并且在前端部分新增了身份认证管理和租户管理的菜单,在 ...
- JS学习阶段性总结-1
各种函数的声明 /** * 函数的声明 */ // 声明一个方法,任意调用 function aaa(args){...} // 声明一个函数并以变量的形式展示出去,因此无法再声明前调用 var fn ...
- SEO大神都是些什么人
http://www.wocaoseo.com/thread-97-1-1.html 貌似好久没有更新seo培训联盟的文章了,最近一直在专心学习其他的东西,前一段写了几篇关于用户需求和体验的文章,但是 ...
- 基于.NetCore3.1系列 —— 日志记录之初识Serilog
一.前言 对内置日志系统的整体实现进行了介绍之后,可以通过使用内置记录器来实现日志的输出路径.而在实际项目开发中,使用第三方日志框架(如: Log4Net.NLog.Loggr.Serilog.Sen ...
- LR监听Linux
1.准备 1)CentOS6.0 2)LR11.0 3)Linux安装包: xinetd-2.3.14-33.el6.i686.rpm (CentOS安装盘自带) rsh-server-0.17-60 ...
- vue 页面首次加载缓慢原因及解决方案
第一次打包vue的项目部署到服务器,发现首次加载特别的缓慢要几十秒才加载出来,完全没有在本地开发环境上那么流畅. 主要原因是页面在打包后没有进行相关的配置导致资源文件特别大,一次想要全部加载完成回特别 ...
- 详解 Python 的二元算术运算,为什么说减法只是语法糖?
原题 | Unravelling binary arithmetic operations in Python 作者 | Brett Cannon 译者 | 豌豆花下猫("Python猫&q ...
- Java网络通信 —— 序列化问题
Java序列化的目的主要有两个: 1.网络传输 2.对象持久化 当选行远程跨迸程服务调用时,需要把被传输的Java对象编码为字节数组或者ByteBuffer对象.而当远程服务读取到ByteBuffer ...
- websocket劫持
WebSockets who is WebSockets? WebSockets是一个能够给单TCP连接提供全双工信道的HTML5特性. 它的持续性连接功能,使得构建B/S模式的实时应用成为可能. W ...
- Java实现获取命令行中的指定数据
构造一个ping的命令类这个类中可以设置需要ping的目标域名类提供方法public void exec();方法执行完毕后可以读取ping的次数,ping的成功回应包个数ping的丢包个数,ping ...