java虚拟机和内存优化总结

前一段时间总结了spring和springmvc相关的知识,面试中常问到的除了这些基本的框架之外,还有底层的基础知识,比如与java虚拟机相关的知识点,这一部分也是面试中经常问到的,在面试中高级java工程师的时候,这一部分是很重要的一个点,倘若一个程序员在这一块没有了解或者看过学习过相关的知识,那么他的基础就是相对薄弱的,面试成功的可能性也会降低很多.
这篇文章会把java的整体运行结构和jvm的关系做个梳理,但是不再用大篇幅的文字叙述的内容,这样不容易记忆,而且容易产生厌看的情绪.所以我决定使用采用绘图+少部分文字描述为主.
一、弄明白java的整体运行结构与jvm的关系
1. jvm是什么?
Java虚拟机(英语:Java Virtual Machine,缩写为JVM),一种能够运行Java bytecode的虚拟机,以堆栈结构机器来进行实做。最早由太阳微系统所研发并实现第一个实现版本,是Java平台的一部分,能够运行以Java语言写作的软件程序Java虚拟机有自己完善的硬体架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码-字节码,就可以在多种平台上不加修改地运行。通过对中央处理器CPU所执行的软件实现,实现能执行编译过的Java程序码与应用程序)。
作为一种编程语言的虚拟机,实际上不只是专用于Java语言,只要生成的编译文件匹配JVM对加载编译文件格式要求,任何语言都可以由JVM编译运行。此外,除了甲骨文,也有其他开源或闭源的实现。--摘自维基百科
2.java运行过程与jvm关系

上图能够清晰的展示我们从新编译一个java类到jvm中执行的全部流程,对堆栈等地方的功能做一个解释:
- 堆:java的引用传递实现,依靠的就是堆内存,同一块堆内存可以被不同的栈内存所指向;
- 栈:程序运行的单位,里面存储的信息都与当前的线程有关系,包括局部变量,程序的运行状态,方法返回值等;
- 方法区:在进行递归调用时,所保存的堆栈内容,它由局部变量表,操作数栈,当前方法所属的类的运行时常量的引用,返回地址等;
- 程序计数器:一块非常小的内存空间,主要用来做一个计数操作,对象的晋升问题(关系到垃圾回收(GC)).
二、堆内存组织结构以及与内存有关的参数设置(优化)
在整个jvm运行时数据区,要对jvm进行优化,那么堆内存是重点优化对象.原因是栈本身所占的内存比率很小,而java中所有new对象全部放在堆内存区域.那么对这些对象的回收控制策略就非常重要.
1.堆内存的内部结构

上图展示了堆内存的内部结构,值得注意的是,在1.8之前和之后,java的永久代被取消,被元空间所代替(元空间就是电脑本省的物理内存),下面对各个区的作用做简单的解释:
年轻代:
- Eden区:新生的小对象,每当使用关键字new的时候,默认都会在此空间进行对象创建,如果创建的对象过多,那么最终的的结果就是Eden区的空间爆满,此时会发生晋级操作(在经历若干次minorGC后还保留的对象,晋升到存活区)
存活区:minorGC存活的对象保存的区域,存活区有两块空间S0和S1,有一块始终为空,该区域保存对象向老年代晋升
(停止-复制算法);
老年代:经历了数次GC之后还保留的对象,这些对象经历了多次GC仍然存活,但是也有可能在接下来的某一次被清除掉,同时要注意,假如是new一个很大的对象,那么是直接保存到老年代来,如果老年代空间不够了,会出现MajorGC(FullGC)进行老年代的清理,非常耗费性能(不建议使用system.gc()的原因);
在发生MajorGC的时候,jvm会检查每次晋升入老年代的对象的大小是否大于老年代剩余空间的大小,若大于,直接触发一次FullGC,否则可以自定义是否允许担保失败(关键字设置:XX:+HandlePromotionFailure)(标记-清理算法);
元空间(永久代):jdk1.8之后,取消了永久代,变成了元空间,不再在堆内存里面保存类,字符串常量等,采用了元空间之后,不会再出现堆溢出的异常.2. 重要参数
通过调整jvm的相关参数,可以优化堆内存,提高jvm的运行效率,下面对几个重要参数做一下总结:
- -Xms:设置初始化的内存分配大小,,默认采用的大小为物理大小的1/64;
- -Xmx:设置最大的内存可用空间,,默认采用的大小为物理大小的1/4;
- -Xmn:设置年轻代大小,默认采用的大小为物理大小的1/64;
-Xss:设置每一个线程所占用的栈的大小
三、GC算法
在jdk1.7之后,正式发布了G1回收算法;
在此之前,GC算法的发展进程如下:
- Serial(串行)收集器
在jdk1.3.1之前,java虚拟机仅仅能使用Serial收集器。 Serial收集器是一个单线程的收集器,但它的“单线程”的意义并不仅仅是说明它只会使用一个CPU或一条收集线程去完成垃圾收集工作,更重要的是在它进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束。 - Parallel(并行)收集器
Parallel收集器也称吞吐量收集器,相比Serial收集器,Parallel最主要的优势在于使用多线程去完成垃圾清理工作,这样可以充分利用多核的特性,大幅降低gc时间。 - CMS(并发)收集器
CMS收集器在Minor GC时会暂停所有的应用线程,并以多线程的方式进行垃圾回收。在Full GC时不再暂停应用线程,而是使用若干个后台线程定期的对老年代空间进行扫描,及时回收其中不再使用的对象。 G1(并发)收集器
G1收集器(或者垃圾优先收集器)的设计初衷是为了尽量缩短处理超大堆(大于4GB)时产生的停顿。相对于CMS的优势而言是内存碎片的产生率大大降低。
以上就是GC算法发展史,具体的各个算法有什么不同,暂时还没有特别深入的研究和比较,后续会再开一篇补上.总结
这篇文章对java运行的流程和jvm的关系,以及jvm的内部结构,和jvm的堆内存优化,做了一个总结,但是GC算法是一个大头,一篇文章的篇幅实在是无法详述,后续再接再厉,争取把这一快吃透.
java虚拟机和内存优化总结的更多相关文章
- Java虚拟机之内存区域
原创文章,转载请标明出处! 目录 一.背景 二.运行时内存区域概述 1.官方描述 2.中文翻译 3.内存区域简述 4.运行时数据区简图 5.运行时数据区详图 三.JVM线程 JVM数据区域与线程关系 ...
- 如何写出让java虚拟机发生内存溢出异常OutOfMemoryError的代码
程序小白在写代码的过程中,经常会不经意间写出发生内存溢出异常的代码.很多时候这类异常如何产生的都傻傻弄不清楚,如果能故意写出让jvm发生内存溢出的代码,有时候看来也并非一件容易的事.最近通过学习< ...
- 深入理解java虚拟机【内存溢出实例】
通过简单的小例子程序,演示java虚拟机各部分内存溢出情况: (1).java堆溢出: Java堆用于存储实例对象,只要不断创建对象,并且保证GC Roots到对象之间有引用的可达,避免垃圾收集器回收 ...
- 从Java虚拟机的内存区域、垃圾收集器及内存分配原则谈Java的内存回收机制
一.引言: 在Java中我们只需要轻轻地new一下,就可以为实例化一个类,并分配对应的内存空间,而后似乎我们也可以不用去管它,Java自带垃圾回收器,到了对象死亡的时候垃圾回收器就会将死亡对象的内存回 ...
- Java虚拟机:内存模型详解
版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 我们都知道,当虚拟机执行Java代码的时候,首先要把字节码文件加载到内存,那么这些类的信息都存放在内存中的哪个区域呢?当我们创建一个对象实 ...
- 初识:java虚拟机的内存划分
什么是内存? 内存是计算机中的重要原件,临时存储区域,作用是运行程序.我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的,必须放进内存中才能运行,运行完毕后会清空内存.Java虚拟机要运行程序 ...
- java虚拟机的内存模型
一.为什么要了解java虚拟机的内存模型 java虚拟机作为java代码运行的平台,是java技术的基石.了解java虚拟机的内存模型也就变得十分必要.它能帮助我们更好的了解java代码的运行机制,更 ...
- java虚拟机的内存机制
我们都知道,java程序的跨平台性离不开java虚拟机,虚拟机隔绝了底层操作系统,使得java程序可以直接运行在虚拟机之上.所以,对java的学习,离不开对java虚拟机的学习与了解.下面简单整理下j ...
- Java虚拟机的内存管理
众所周知,Java程序员写的代码是没有办法控制Java对象的内存释放的,完全有JVM暗箱操作. 虽然程序员把内存的释放的任务都交给了Java虚拟机,但是并不代表Java程序就不存在内存泄漏. 反而,某 ...
随机推荐
- java——collection总结
Collection 来源于Java.util包,是非常实用常用的数据结构!!!!!字面意思就是容器.具体的继承实现关系如下图,先整体有个印象,再依次介绍各个部分的方法,注意事项,以及应用场景. ...
- 七层协议&网络配置
1.输入CMD 2.ipconfig-all 可查看详细的电脑网络配置,子网掩码(subnet mask)又叫网络掩码.地址掩码.子网络遮罩,它是一种用来指明一个IP地址的哪些位标识的是主机所在的子网 ...
- C#异步方法
Task MainTask; MainTask = Task.Factory.StartNew(() => { //耗时的异步逻辑 });
- js Base64 转化成图片格式
function dataURLtoFile(dataurl, filename = 'file') { let arr = dataurl.split(',') let mime = arr[0]. ...
- html--form表单
<!-- form 标签 作用:收集并提交用户的信息 属性: id 表单的id,用于js获取表单 name 表单的名字,用于js获取表单 action 表单提交的地址 method 表单提交 ...
- [python]global与nonlocal关键字
在Python中,当引用一个变量的时候,对这个变量的搜索是按找本地作用域(Local).嵌套作用域(Enclosing function locals).全局作用域(Global).内置作用域(bui ...
- mysql 数据插入时的问题
问题:在实现json串插入到数据库的时候发现中文utf-8传入的.但到数据中的时候反斜杠\就不见了,导致后面显示的时候也不能正常显示. 解决方法:comment=comment.replace(&qu ...
- laravel框架memcached的使用
在laravel配置及使用使用 Memcached 缓存要求安装了Memcached PECL 包,即 PHP Memcached 扩展.你可以在配置文件 config/cache.php 中列出所有 ...
- 云栖大会day2总结 上午
第二天上午主要是参与了开发者专场 上 09:00-09:40 线上线下融合时代的工程师成长 李佩 饿了么高级算法总监 09:40-10:20 如何统一阿里巴巴代码规范:探寻工程师文化之路 玄坛 阿里巴 ...
- gitkraken clone报错 Configured SSH key is invalid
gitkraken clone远程仓库时报错 Configured SSH key is invalid. Please confirm that is properly associated wit ...