JVM总结(一)
JVM总结(1)
1、JVM组成:
JVM由类加载器子系统、运行时数据区、执行引擎以及本地方法接口组成。
2、JVM运行原理:
Java源文件经编译器,编译成字节码程序,通过JVM将每一条指令翻译成不同平台机器码,通过特定平台运行。
3.Java垃圾回收区域
Java垃圾回收只针对堆和方法区的内存。
线程方法区、虚拟机栈和程序计数器随着线程而生,随线程而灭因此不用管。
4.如何确定垃圾
采取引用计数是否可行?即统计有多少人引用了,如果0人引用,则判断为垃圾。缺点是:东西很多时,消耗太大;环形引用:A引用了B,B引用了A,其实A\B都是垃圾,但他们引用永远都是1,不会被回收掉,陷入了死循环。
可达性算法:从垃圾回收的根出发判断是否可见,这也是JVM采用的可达性分析算法。
如图object5,6,7都是可回收的垃圾
5.垃圾回收算法
标记--清除算法:缺点碎片化很严重,导致程序运行时需要分配较大的对象时,无法找到足够的内存存放,不得不提前再进行一次GC
标记--整理算法:缺点是实际消耗很大,垃圾是一块一块的,要把回收空出的内存向前移动,不能整块移动,需要切成很多小块移动,所以消耗很大。
拷贝算法:先把内存分为两块,内存1往内存2拷贝,内存1全部清除,缺点是内存只能使用一般,浪费性能。
JVM实际使用的分代垃圾回收算法,就是把上面的的朴素算法综合一下
基础假设:大部分对象只存在很短的时间,这个假设确实也是对的
基于上面的假设,JVM将内存分为新生代和老生代。大部分只存在很短的时间,就放在新生代。对于少部分存在很长时间的对象,放在老生代去。
对新生代和老生代采取不同的做法
新生代经常性进行GC,因此要优化性能,采取类似Copy算法
将新生代分为Eden,Survivor1和Survivor2。
Eden是要回收的区域。1表示存活了1次垃圾回收,2表示存活了2次垃圾回收。
第一次回收,从Eden回收存活下来的对象放入Survivor1,然后清掉Eden。
又产生了垃圾
第二次回收,从Eden和Survivor1存活的对象放入Survivor2
清理掉eden和survivor1,如此反复进行,当survivor不够用时,就把survivor中年纪大的对象放入老生代
Full GC是对老生代进行GC,使用的是标记--整理算法
6、内存分配与回收策略
对象优先在Eden区分配
老年GC(full GC/Major GC)一般比新生代GC(Minor GC)慢十倍以上
大对象直接进入老年代,大对象是指需要大量连续内存空间的Java对象,比如很长的字符串或者数组。
长期存活的对象将进入老年代。默认15岁
动态对象年龄判定。如果Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代。
空间分配担保:当出现大量对象Minor GC后仍然存活的情况,需要老年代进行分配担保,让Survivor无法容纳的对象直接进入老年代。
JVM垃圾回收参数
持久代(JDK8改进成元空间)
如何解决OutOfMemoryError:PermGen Space的问题?
使用-XX:MaxPermSize调整,调大一点
Java 1.8帮我们做了改进,取消了持久代,改进成元空间
元空间
调用String.intern()方法的时候,会将共享池中的字符串与外部的字符串(s)进行比较,如果共享池中有与之相等的字符串,则不会将外部的字符串放到共享池中的,返回的只是共享池中的字符串,如果不同则将外部字符串放入共享池中,并返回其字符串的句柄(引用)-- 这样做的好处就是能够节约空间
一个初始时为空的字符串池,它由类 String 私有地维护。 当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。 它遵循对于任何两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true
谈谈Java垃圾回收机制
回答垃圾回收在什么时候运行?JVM分配内存失败的时候会运行。还可以手动调用System.gc(),JVM会知道你想垃圾回收了,至于到底是否进行GC由JVM自行判断,一般都是进行的。
垃圾回收对什么对象进行回收?从垃圾回收的根节点出发,看的见的不回收,看不见的都回收。
垃圾回收算法对内存划分成了哪些区域?新生代、老生代、Metaspace(元空间),新生代又分为了Eden、Survivor1、Survivor2。并回答具体的算法。
7、垃圾回收器
Serial,单线程,GC的时候必须暂停其他所有工作线程。JVM Client模式下的默认新生代收集器
ParNew,Serial的多线程版本。JVM Server模式下的默认新生代收集器。实现了GC线程与工作线程同时工作。举例就是,一边打扫卫生的时候,还可以一边往地上扔纸屑。
单CPU环境中,ParNew绝对不会有比Serial更好的效果。
Serial和ParNew都是与CMS配合工作。
Parallel Scavenge,关注“吞吐量”。比如JVM总共运行了100分钟,其中GC花了1分钟,那吞吐量就是99%。
新生代的垃圾收集器都是“复制”算法。
Serial Old,单线程,使用“标记-整理”算法负责老年代。
Parallel Old ,多线程,“标记-整理”,和Parallel Scavenge同时使用提高“吞吐量”。
CMS,并发,唯一的“标记-清除”因此可能导致老年代碎片化严重,无法容纳新生代提升上来的大对象,从而CMS失败,退回到Serial Old算法,导致GC时间过长,可以尝试调大Survivor的空间和调整 CMS 垃圾收集在老年代占比达到多少时启动来减少问题发生频率,越早启动问题发生频率越低,但是会降低吞吐量,具体得多调整几次找到平衡点;另外,如果GC频率太快,说明空间不足,首先可以尝试调大新生代空间和晋升阈值,专注最短GC停顿时间,使网站响应更快,服务不会出现长时间停滞。
G1,多线程,分代收集,“标记-整理”,可预测的停顿。如果追求低停顿,可以尝
JVM总结(一)的更多相关文章
- 46张PPT讲述JVM体系结构、GC算法和调优
本PPT从JVM体系结构概述.GC算法.Hotspot内存管理.Hotspot垃圾回收器.调优和监控工具六大方面进行讲述.(内嵌iframe,建议使用电脑浏览) 好东西当然要分享,PPT已上传可供下载 ...
- java 利用ManagementFactory获取jvm,os的一些信息--转
原文地址:http://blog.csdn.net/dream_broken/article/details/49759043 想了解下某个Java项目的运行时jvm的情况,可以使用一些监控工具,比如 ...
- Jvm 内存浅析 及 GC个人学习总结
从诞生至今,20多年过去,Java至今仍是使用最为广泛的语言.这仰赖于Java提供的各种技术和特性,让开发人员能优雅的编写高效的程序.今天我们就来说说Java的一项基本但非常重要的技术内存管理 了解C ...
- JVM类加载
JVM的类加载机制就是:JVM把描述类的class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被JVM直接使用的Java类型 ClassLoader JVM中的ClassLoade ...
- Java虚拟机 JVM
finalize();(不建议使用,代价高,不确定性大) 如果你在一个类中覆写了finalize()方法, 那么你可以在第一次被GC的时候,挽救一个你想挽救的对象,让其不被回收,但只能挽救一次. GC ...
- 在 Linux 中安装 Oracle JDK 8 以及 JVM 的类加载机制
参考资料 该文中的内容来源于 Oracle 的官方文档 Java SE Tools Reference .Oracle 在 Java 方面的文档是非常完善的.对 Java 8 感兴趣的朋友,可以直接找 ...
- MapReduce剖析笔记之六:TaskTracker初始化任务并启动JVM过程
在上面一节我们分析了JobTracker调用JobQueueTaskScheduler进行任务分配,JobQueueTaskScheduler又调用JobInProgress按照一定顺序查找任务的流程 ...
- java太low,又舍不得jvm平台的丰富资源?试试kotlin吧(一)
尝试kotlin的起因 因为各种原因(版权,人员招聘),公司的技术体系从c#转到了java,我花了大概两周的时间来上手java,发现java的语法还是非常简单的,基本看着代码就知道什么意思.学习jav ...
- Jvm --- 常用工具
jps:虚拟机进程状况工具 JVM Process Status Tool. 可以列出所有目前正在运行虚拟机的进程. jps -l 详细参数: -q 输出LVMID,省略主类名称 -m 输出虚拟机进程 ...
- JVM虚拟机结构
JVM的主要结构如下图所示,图片引用自舒の随想日记. 方法区和堆由所有线程共享,其他区域都是线程私有的 程序计数器(Program Counter Register) 类似于PC寄存器,是一块较小的内 ...
随机推荐
- CodeForces 691D:Swaps in Permutation(并查集)
http://codeforces.com/contest/691/problem/D D. Swaps in Permutation You are given a permutation of ...
- Python 爬虫从入门到进阶之路(十六)
之前的文章我们介绍了几种可以爬取网站信息的模块,并根据这些模块爬取了<糗事百科>的糗百内容,本章我们来看一下用于专门爬取网站信息的框架 Scrapy. Scrapy是用纯Python实现一 ...
- SpringBoot 的过滤器
在Springboot里面读封装的一些常用的API,当然对过滤器也不类外了. 首先讲下Spring中的AOP的理解: AOP不是一种具体的技术,而是一种编程思想.在面向对象编程的过程中,我们很容易通过 ...
- Java程序运行原理分析
class文件内容 class文件包含Java程序执行的字节码 数据严格按照格式紧凑排列在class文件的二进制流,中间无分割符 文件开头有一个0xcafebabe(16进制)特殊的标志 JVM运行时 ...
- sqlserver、oracle数据库排序空值null问题解决办法
转:https://www.cnblogs.com/pacer/archive/2010/03/02/1676371.html [sqlserver]: sqlserver 认为 null 最小. 升 ...
- k8s学习 - API
k8s学习 - API 之前对k8s并没有很深入的了解,最近想把手头一个项目全部放到k8s上,以方便部署,需要研究.这里记录一下自己研究过程中头脑中的理解. k8s 和 docker 首先,需要先理解 ...
- C语言学习书籍推荐《C陷阱与缺陷》下载
下载地址:点我 凯尼格 (作者), 高巍 (译者) <C和C++经典著作:C陷阱与缺陷>适合有一定经验的C程序员阅读学习,即便你是C编程高手,<C和C++经典著作:C陷阱与缺陷> ...
- 分布式事务(4)---RocketMQ实现分布式事务项目
RocketMQ实现分布式事务 有关RocketMQ实现分布式事务前面写了一篇博客 1.RocketMQ实现分布式事务原理 下面就这个项目做个整体简单介绍,并在文字最下方附上项目Github地址. 一 ...
- Oracle使用MyBatis中RowBounds实现分页查询
Oracle中分页查询因为存在伪列rownum,sql语句写起来较为复杂,现在介绍一种通过使用MyBatis中的RowBounds进行分页查询,非常方便. 使用MyBatis中的RowBounds进行 ...
- Java编程思想:为什么要使用内部类
public class Test { public static void main(String[] args) { Callbacks.test(); } } /* 为什么需要内部类: 1.可以 ...