深入详解JVM内存模型
JVM内存结构
由上图可以清楚的看到JVM的内存空间分为3大部分:
- 堆内存
- 方法区
- 栈内存
其中栈内存可以再细分为java虚拟机栈和本地方法栈,堆内存可以划分为新生代和老年代,新生代中还可以再次划分为Eden区、From Survivor区和To Survivor区。
其中一部分是线程共享的,包括 Java 堆和方法区;另一部分是线程私有的,包括虚拟机栈和本地方法栈,以及程序计数器这一小部分内存。
存放对象
- 堆存放的是:实例化的对象
- 方法区存放的是:class的相关信息、静态变量、常量池、方法本身
- 栈存放的是:一个个栈帧(Stack Frame),调用一个方法会压入一个栈帧,内容是该方法中的基本类型变量、对象变量的引用、中间变量、形参和方法有关的操作,如出口等
堆内存(Heap)
对于大多数应用来说,Java 堆(Java Heap)是Java 虚拟机所管理的内存中最大的一块。Java 堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。
此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。
堆内存是所有线程共有的,可以分为两个部分:年轻代和老年代。
下图中的Perm代表的是永久代,但是注意永久代并不属于堆内存中的一部分,同时jdk1.8之后永久代已经被移除。
新生代 ( Young ) 与老年代 ( Old ) 的比例的值为 1:2 ( 该值可以通过参数 –XX:NewRatio 来指定 )
默认的,Eden : from : to = 8 : 1 : 1 ( 可以通过参数 –XX:SurvivorRatio 来设定 ),即: Eden = 8/10 的新生代空间大小,from = to = 1/10 的新生代空间大小。
方法区(Method Area)
方法区也称"永久代",它用于存储虚拟机加载的类信息、常量、静态变量、是各个线程共享的内存区域。
在JDK8之前的HotSpot JVM,存放这些”永久的”的区域叫做“永久代(permanent generation)”。永久代是一片连续的堆空间,在JVM启动之前通过在命令行设置参数-XX:MaxPermSize来设定永久代最大可分配的内存空间,默认大小是64M(64位JVM默认是85M)。
随着JDK8的到来,JVM不再有 永久代(PermGen)。但类的元数据信息(metadata)还在,只不过不再是存储在连续的堆空间上,而是移动到叫做“Metaspace”的本地内存(Native memory。
方法区或永生代相关设置
- -XX:PermSize=64MB 最小尺寸,初始分配
- -XX:MaxPermSize=256MB 最大允许分配尺寸,按需分配
- XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled 设置垃圾不回收
- 默认大小
- -server选项下默认MaxPermSize为64m
- -client选项下默认MaxPermSize为32m
虚拟机栈(JVM Stack)
描述的是java方法执行的内存模型:每个方法被执行的时候都会创建一个"栈帧",用于存储局部变量表(包括参数)、操作栈、方法出口等信息。每个方法被调用到执行完的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
本地方法栈(Native Stack)
本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务。
程序计数器(PC Register)
程序计数器是用于标识当前线程执行的字节码文件的行号指示器。多线程情况下,每个线程都具有各自独立的程序计数器,所以该区域是非线程共享的内存区域。
当执行java方法时候,计数器中保存的是字节码文件的行号;当执行Native方法时,计数器的值为空。
直接内存
直接内存并不是虚拟机内存的一部分,也不是Java虚拟机规范中定义的内存区域。jdk1.4中新加入的NIO,引入了通道与缓冲区的IO方式,它可以调用Native方法直接分配堆外内存,这个堆外内存就是本机内存,不会影响到堆内存的大小。
JVM内存参数设置
- -Xms设置堆的最小空间大小。
- -Xmx设置堆的最大空间大小。
- -Xmn:设置年轻代大小
- -XX:NewSize设置新生代最小空间大小。
- -XX:MaxNewSize设置新生代最大空间大小。
- -XX:PermSize设置永久代最小空间大小。
- -XX:MaxPermSize设置永久代最大空间大小。
- -Xss设置每个线程的堆栈大小
- -XX:+UseParallelGC:选择垃圾收集器为并行收集器。此配置仅对年轻代有效。即上述配置下,年轻代使用并发收集,而年老代仍旧使用串行收集。
- -XX:ParallelGCThreads=20:配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。
典型JVM参数配置参考:
- java-Xmx3550m-Xms3550m-Xmn2g-Xss128k
- -XX:ParallelGCThreads=20
- -XX:+UseConcMarkSweepGC-XX:+UseParNewGC
-Xmx3550m:设置JVM最大可用内存为3550M。
-Xms3550m:设置JVM促使内存为3550m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。
-Xmn2g:设置年轻代大小为2G。整个堆大小=年轻代大小+年老代大小+持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,官方推荐配置为整个堆的3/8。
-Xss128k:设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大 小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000 左右。
深入详解JVM内存模型的更多相关文章
- 直通BAT必考题系列:深入详解JVM内存模型与JVM参数详细配置
VM基本是BAT面试必考的内容,今天我们先从JVM内存模型开启详解整个JVM系列,希望看完整个系列后,可以轻松通过BAT关于JVM的考核. BAT必考JVM系列专题 1.JVM内存模型 2.JVM垃圾 ...
- 深入详解JVM内存模型与JVM参数详细配置
对于大多数应用来说,Java 堆(Java Heap)是Java 虚拟机所管理的内存中最大的一块.Java 堆是被所有线程共享的一块内存区域,在虚拟机启动时创建. JVM内存结构 由上图可以清楚的看到 ...
- 详解JVM内存模型与JVM参数详细配置
对于大多数应用来说,Java 堆(Java Heap)是Java 虚拟机所管理的内存中最大的一块.Java 堆是被所有线程共享的一块内存区域,在虚拟机启动时创建. JVM内存结构 由上图可以清楚的看到 ...
- 「跬步千里」详解 Java 内存模型与原子性、可见性、有序性
文题 "跬步千里" 主要是为了凸显这篇文章的基础性与重要性(狗头),并发编程这块的知识也确实主要围绕着 JMM 和三大性质来展开. 全文脉络如下: 1)为什么要学习并发编程? 2) ...
- Java虚拟机详解----JVM内存结构
http://www.cnblogs.com/smyhvae/p/4748392.htm 主要内容如下: JVM启动流程 JVM基本结构 内存模型 编译和解释运行的概念 一.JVM启动流程: JVM启 ...
- BAT面试必问题系列:深入详解JVM 内存区域及内存溢出分析
前言 在JVM的管控下,Java程序员不再需要管理内存的分配与释放,这和在C和C++的世界是完全不一样的.所以,在JVM的帮助下,Java程序员很少会关注内存泄露和内存溢出的问题.但是,一旦JVM发生 ...
- [转帖]详解JVM内存布局及GC原理,值得收藏
概述 https://www.toutiao.com/i6731345429574713868/ java发展历史上出现过很多垃圾回收器,各有各的适应场景,不仅仅是开发,作为运维也需要对这方面有一定的 ...
- JVM内存模型和结构详解(五大模型图解)
JVM内存模型和Java内存模型都是面试的热点问题,名字看感觉都差不多,实际上他们之间差别还是挺大的. 通俗点说,JVM内存结构是与JVM的内部存储结构相关,而Java内存模型是与多线程编程相关@mi ...
- JVM完整详解:内存分配+运行原理+回收算法+GC参数等
不管是BAT面试,还是工作实践中的JVM调优以及参数设置,或者内存溢出检测等,都需要涉及到Java虚拟机的内存模型.内存分配,以及回收算法机制等,这些都是必考.必会技能. JVM内存模型 JVM内存模 ...
随机推荐
- Visual Studio Code工具使用及配置
最近迷上了这个工具,启动速度快,好多插件.唯一不满意的地方就是svn版本控制工具.下面发现我装的一些插件及配置: 我安装的一些插件: 上面是我装的插件,等有时间再解释下插件的作用. 接下来说下配置: ...
- STL源码之traits编程技法
摘要 主要讨论如何获取迭代器相应型别.使用迭代器时,很可能用到其型别,若需要声明某个迭代器所指对象的型别的变量,该如何解决.方法如下: function template的参数推导机制 例如: tem ...
- Maven依赖中scope的含义
https://www.jianshu.com/p/7145f01ac3ad Maven依赖中scope的含义 整理一下Maven中Scope的详细作用,都是抄的别人内容整理了一下.参考: https ...
- linux配置ssh免密钥登录
https://blog.csdn.net/xiaoyi23000/article/details/80597516 1.执行命令ssh-keygen -t rsa,生成公钥和私钥 2.会在当前用户的 ...
- GPU机器安装paddle
安装基础包 yum -y install epel-release yum -y install kernel-devel yum -y install dkms 编辑文件 /etc/default/ ...
- LRU缓存实现
LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高” 在java中可以采用Linke ...
- java对象池化技术
https://blog.csdn.net/tiane5hao/article/details/85957840 文章目录 先写一个简单通用的对象池 通过上面的通用池实现jedis连接池 连接池测试 ...
- Codeforces Round #604 (Div. 2) (题解)
A. Beautiful String (暴力) 题目链接 题目大意: 给定一个字符串,只有 \(?a\ b\ c\ ?\) ,问是否存在一种将所有的 \(?\) 替换成 \(a\ b\ c\) ,使 ...
- python 开机 定时启动
Windows开机自动运行.py文件1.找到写好的.py文件,例如我的.py文件路径:D:\编程测试文件\untitled\03131105.py 2.选中文件03131105.py,右键——属性—— ...
- DRF框架(二)——解析模块(parsers)、异常模块(exception_handler)、响应模块(Response)、三大序列化组件介绍、Serializer组件(序列化与反序列化使用)
解析模块 为什么要配置解析模块 1)drf给我们提供了多种解析数据包方式的解析类 form-data/urlencoded/json 2)我们可以通过配置来控制前台提交的哪些格式的数据后台在解析,哪些 ...