小丁在加班之JVM优化-内存结构
JVM优化-内存结构
- 简介
- 内存结构
- 1.程序计数器
- 2.虚拟机栈
- 2.1 栈内存溢出
- 2.2 线程运行诊断
- 3.本地方法栈
- 4.堆
- 4.1堆内存溢出
- 5.方法区
- 5.1 方法区内存溢出
- 5.2 运行时常量池
- 5.3 StringTable 特性
- 5.4 StringTable 性能调优
- 6 直接内存
- 6.1 分配和回收原理
简介
定义:
Java Virtual Machine - java 程序的运行环境 (java 二进制字节码的运行环境)
好处:
- 一次编写,到处运行
- 自动内存管理,垃圾回收功能
- 数组下标越界检查
- 多态
jvm、jre、jdk之间的关系
意义
- 理解底层的实现原理
- 中高级程序员必备技能
内存结构
1.程序计数器
Program Counter Register 程序计数器(寄存器)- 记住下一条jvm指令的执行地址
特点
- 是线程私有的
- 不会存在内存溢出
2.虚拟机栈
Java Virtual Machine Stacks (Java 虚拟机栈)
- 每个线程运行时所需要的内存,称为虚拟机栈
- 每个栈由多个栈帧(Frame)组成,对应着每次方法调用时所占用的内存
- 每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法
问题辨析
- 垃圾回收是否涉及栈内存?
答:不涉及,栈会在方法调用结束后不再占用内存 - 栈内存分配越大越好吗?
答:不是,栈内存越大支持并发的线程数越少,因为最大内存有限 - 方法内的局部变量是否线程安全?
答:如果方法内局部变量没有逃离方法的作用范围,它就是线程安全的;如果是局部变量引用了对象,并逃离方法的作用范围,需要考虑线程安全。
2.1 栈内存溢出
java.lang.StackOverflowError
- 栈帧过多导致栈内存溢出
- 栈帧过大导致栈内存溢出
2.2 线程运行诊断
cpu 占用过多
- 用 top 定位哪个进程对 cpu 的占用过高
- ps H -eo pid,tid,%cpu|grep 进程 id (用ps命令进一步定位的哪个线程引起的 cpu 占用过高)
- jstack 进程 id,找到有问题的线程,进一步定位到问题代码的源码行号
死锁
jstack 进程 id,找到有问题的线程,进一步定位到问题代码的源码行号
3.本地方法栈
Native Method Stacks 本地方法栈 - 为本地方法运行提供运行空间
4.堆
Heap 堆 - 通过 new 关键字,创建对象都会使用堆内存
特点:
- 它是线程共享的,堆中对象都需要考虑线程安全问题
- 有垃圾回收机制(回收不再引用的对象)
4.1堆内存溢出
java.lang.OutofMemoryError : Java heap space
- jps 工具 - 查看当前系统中有哪些 java 进程
- jmap 工具 - 查看堆内存占用情况 jmap - heap 进程id
- jconsole 工具 - 图形界面的多功能检测工具,可以连续监测(jdk自带)
5.方法区
组成:
5.1 方法区内存溢出
java.lang.OutOfMemoryError : Metaspace - 元空间内存溢出( jdk 1.8 以后)
java.lang.OutOfMemoryError : PermGen space - 永久代内存溢出( jdk 1.8 以前)
5.2 运行时常量池
- 常量池,就是一张表,虚拟机指令根据这张表找到要执行的类名、方法名、参数类型、字面量等信息
- 运行时常量池,常量池是 *.class 文件中的,当该类被加载,它的常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址
5.3 StringTable 特性
常量池中的字符串只是符号,第一次用到时候才会变为对象
利用串池的机制,来避免重复创建字符串对象
字符串变量拼接的原理是 StringBuilder (1.8)
字符串常量拼接的原理是编译期优化
可以使用 intern 方法,主动将串池中还没有的字符串对象放入串池
jdk1.8 将这个字符串对象尝试放入串池,如果有则不会放入,没有则会放入,并返回串池中的对象
jdk1.6 将这个字符串对象尝试放入串池,如果有则不会放入,没有则会把此对象拷贝一份,放入串池,并返回串池中的对象
String s1 = "a";
String s2 = "b";
String s3 = "a"+"b";//常量池 ab
String s4 = s1 + s2;//堆 new String("ab")
String s5 = "ab";
String s6 = s4.intern();
//问
System.out.println(s3 == s4);//false
System.out.println(s3 == s5);//true
System.out.println(s3 == s6);//trueString x2 = new String(orignal "c")+new String(orignal "d");//堆 new String("cd")
String x1 = "cd";
x2.intern();
//问
System.out.println(x1 == x2);//false
//若调换x1 x2生成位置,jdk1.6下,
System.out.println(x1 == x2);//false
5.4 StringTable 性能调优
- 调整 -XX:StringTableSize=桶个数
- 考虑将字符串对象是否入池,以减少重复字符串占用内存
6 直接内存
- 常见于 NIO 操作时,用于数据缓冲区
- 分配回收成本较高,但读写性能高
- 不受 JVM 内存回收管理
普通的 java 文件读写,冗余了数据复制操作
直接内存的文件读写,使用了 java 与系统可共享读写的区域,提升了效率
6.1 分配和回收原理
- 底层使用了 Unsafe 对象完成直接内存的分配回收,并且回收需要主动调用 freeMemory 方法
- ByteBuffer 的实现类内部,使用了 Cleaner (虚引用)来检测 ByteBuffer 对象,一旦 ByteBuffer 对象被垃圾回收,那么就会由 ReferenceHandler 线程通过 Cleaner 的 clean 方法调用 freeMemory 来释放直接内存
小丁在加班之JVM优化-内存结构相关推荐
- JVM之内存结构图文详解
点击蓝色"程序猿DD"关注我 回复"资源"获取独家整理的学习资料! 对于开发人员来说,如果不了解Java的JVM,那真的是很难写得一手好代码,很难查得一手好bu ...
- JVM之内存结构详解
对于开发人员来说,如果不了解Java的JVM,那真的是很难写得一手好代码,很难查得一手好bug.同时,JVM也是面试环节的中重灾区.今天开始,<JVM详解>系列开启,带大家深入了解JVM相 ...
- JVM(一)JVM虚拟机内存结构 和 JAVA内存模型(JMM)
本文转自:浅析java内存模型--JMM(Java Memory Model) - 路易小七 - 博客园,尊重作者,转载请注明出处~ JVM虚拟机内存结构 和 JAVA内存模型 是两个不同的概念 JV ...
- 一文解析JVM的内存结构,身为程序员还不弄懂JVM怎么行
欢迎关注专栏:Java架构技术进阶.里面有大量batj面试题集锦,还有各种技术分享,如有好文章也欢迎投稿哦.微信公众号:慕容千语的架构笔记.欢迎关注一起进步. 前言 Jvm的内存结构是由<jav ...
- JVM的内存结构,Eden和Survivor比例;JVM中一次完整的GC流程,对象如何晋升到老年代,说说你知道的几种主要的JVM参数;CMS 常见参数解析;.你知道哪几种垃圾收集器,各自的优缺点
47.JVM的内存结构,Eden和Survivor比例 49.JVM中一次完整的GC流程是怎样的,对象如何晋升到老年代,说说你知道的几种主要的JVM参数 50.-XX:+CMSScavengeBefo ...
- jvm虚拟机内存结构_JVM体系结构101:了解您的虚拟机
jvm虚拟机内存结构 Java虚拟机(JVM)架构和Java字节码101的初学者速成班 Java应用程序无处不在,它们在我们的手机,平板电脑和计算机上. 在许多编程语言中,这意味着多次编译代码以使其在 ...
- 一文搞定JVM的内存结构
目录 1.简介 2.程序计数器(PC寄存器) 2.1 功能演示 2.2 关于PC的面试题 3.虚拟机栈 3.1 初识虚拟机栈 3.2 栈帧的内部结构 3.2.1 局部变量表 3.2.2 操作数栈 3. ...
- JVM详解【三】JVM的内存结构
JVM的内存区域 JVM的内存区域分为线程私有区域(程序计数器.虚拟机栈.本地方法区).线程共享区域(堆.方法区)和直接内存,如图所示 线程私有区域的生命周期与线程相同,随线程启动而创建,随线 ...
- jvm优化——内存模型
这篇主要来介绍jvm中的内存模型 一.jvm 内存模型划分 根据JVM规范,JVM 内存共分为:方法区,虚拟机栈,本地方法栈,堆,程序计数器五个部分 方法区(线程共享) 被所有方法线程共享的一块内存区 ...
- 【JVM】内存结构(下)
10. 对象实例化内存布局与访问定位 10.1 对象的实例化 10.1.1 创建对象的方式 10.1.2 创建对象的步骤 public class ObjectTest {public static ...
最新文章
- JS对象直接量,数组直接量和函数直接量
- 用漫画了解 Linux 内核到底长啥样
- R语言为dataframe添加新的数据列(横向拼接、Appending columns,Unioning columns):使用R原生方法、data.table、dplyr等方案
- Kafka【入门】就这一篇!
- python列表获取最后一个元素的方法_在Python中获取列表的最后一个元素
- matlab accuracy 存,matlab 绘制caffe accuracy与loss曲线
- 第三方Charts绘制图表四种形式:饼状图,雷达图,柱状图,直线图
- iOS App 签名的原理(转)
- seo主要做什么(记录你工作的内容)
- 大四学生会玩:拍“恐怖”毕业照走红网络,堪比惊悚片
- 【有料】Java线程池实现原理及其在美团业务中的实践
- 统计学中的真阳性(TP),假阴性(FN),假阳性(FP),真阴性(TN)怎么理解?
- jsPlumb使用学习-在线流程设计器demo参考说明
- linux 计价软件,思谷电话计费系统Linux版免费版_思谷电话计费系统Linux版官方下载_思谷电话计费系统Linux版5.1-华军软件园...
- 青海省谷歌地球高程DEM等高线下载
- 免费在线html文档,HTML标签大全(最全的html标签文档).doc
- Java基础(2)面向对象的理解
- 无领导小组讨论面试真题解析(五)——沙漠求生记
- 打开ftp服务器上的文件夹发生错误 请检查是否有权向访问该文件夹
- 河北省邢台市谷歌高清卫星地图下载
热门文章
- Excel常用技巧笔记
- 心无界,牧云端:华为云与人工智能的野望
- 解决AndroidStudio中使用.9图片不生效的问题
- 单元测试总结反思_单元考试反思总结
- 家用 linux 路由器教程,Ubuntu 搭建无线路由器
- win7硬盘安装ubuntu经验
- element-ui el-dialog 的form 表单验证关闭时清除错误验证信息
- vs无法打开源文件_南美预选:乌拉圭vs巴西,双方核心都无法上场,谁来打开胜利之门?...
- 深入了解ElasticSearch的Nested数据类型
- PS制作 LOGO图片