当前位置: 首页 > 编程日记 > 正文

JVM内存管理学习总结(一)

I.JVM进程的生命周期

  1. JVM实例的生命周期和java程序的生命周期保持一致,即一个新的程序启动则产生一个新的JVM进程实例,程序结束则JVM进程实例伴随着消失。那么程序启动和程序终止就是JVM实例生命周期的两个边界,两个边界点可以这么理解:一个拥有程序入口(main函数)的class在执行main方法时,相应的JVM就被创建了(即JVM生命周期的起点),当由此main函数启动的所有非守护线程都终止时,JVM即退出(JVM实例生命周期的终点)。举个实例来描述一下JVM实例的生命周期:

    (1) JVMInstance.java

    public class JVMInstance {public static void main(String[] args) {System.out.println("hello world!");}
    }
    

    (2) javac JVMInstance.java 编译源码生成class文件 
    (3) java JVMInstance 
    在用java 命令执行编译好的字节码文件时,java命令会调用java launcher来创建JVM实例,而java.exe的源代码在jdk/src/share/bin/java.c定义(可以在openJDK中看到其中的源代码)。 java.c中主要包含了两个主要的函数:

    int main(int argc, char ** argv); int JNICALLJavaMain(void * _args); 其中主要完成的功能是新建JVM实例进程,实例化一些守护线程,包括监视器线程(WatcherThread),编译器线程(Compiler Thread),GC线程(GC Thread)。(具体源代码可以细扣一下,有现成的研究大家也分享一下) //TODO ps:学习一下java.c 源代码

II.JVM内存模型

在内存结构上每个JVM实例都有自己的一套内存模型(即:堆,方法区,方法栈,本地方法栈,程序技术器),当JVM实例创建时内存模型也随之创建,没猜错的话java.c的这段代码就是用来分配JVM实例内存的:

{int i;original_argv = (char**)JLI_MemAlloc(sizeof(char*)*(argc+1));for(i = 0; i < argc+1; i++) {
original_argv[i] = argv[i];}
}CreateExecutionEnvironment(&argc, &argv,jrepath, sizeof(jrepath),jvmpath, sizeof(jvmpath),original_argv);
...

JVM实例的内存模型结构入下图(参考《深入理解java虚拟机》):  上图中标出了红框和绿框,其中红框代表在一个JVM进程实例内所有线程共享的内存模型区域,绿框表示线程内存数据隔离的区域,即方法区和堆中的数据JVM进程内线程共享,栈和程序计数器每个线程有自己的一套。(看过一些博客把方法区也画入了堆内存结构中,感觉不是很合理,虽然java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做Non-heap(非堆))。方法区主要存储:类加载的信息,常量,静态变量,即时编译器编译后的代码等数据。堆内存又分为 Yong、Tenured、Perm。虚拟机栈是执行普通方法是需要用的,本地方法栈就是执行本地方法栈的时候用的。程序计数器就是辅助程序执行用的,记录程序指令指针。 JVM执行引擎是JVM实例进程中的一个线程,用来执行字节码指令的。

III.JVM内存垃圾回收机制及常用垃圾回收器

(1)分代回收:在运行的程序中,会创建大量端生命周期的对象和小部分长生命周期的对象。对于短生命周期对象,垃圾回收线程就需要频繁的检测释放,对于长周期的对象垃圾回收检测线程探测频率就可以少一点。为了满足这种需求SUN的JVM内存是分代管理,分代回收的(说白了分代管理就是为了分代回收,哪天如果不需要分代回收了,那分代管理机制也就不需要了,我个人觉得哈)。

(2)常用的垃圾回收算法:

标记清除算法: 概述:回收过程分两个阶段,即先“标记” 再 “清除”,首先GC线程根据根搜索算法以及回收判定策略,判断对象是否需要被回收,将需要被回收的对象全都标记出来,然后统一回收掉。这种算法是比较基础的算法,后续的算法基本是基于这种算法的。 主要缺点:一个是效率问题,标记和清除过程效率都不高;另外一个是空间问题,标记清除之后会产生不连续的内存碎片(如果空间碎片太多,当分配一个大对象的时候,因为找不到一块合适的内存区域,就会提前出发一次GC操作)。

复制算法: 复制算法基本思想就是,将内存分成大小相等的两块,每次只使用其中的一块。当其中一块内存用完了,就将活着的对象按序摆放到另外一块内存中,然后将另一块内存清理掉。 优缺点:优点就是与标记清除算法相比,效率明显提高了,并且不会产生内存碎片。缺点也是显而易见就是内存需求更大了,每次都需要有一块内存闲置。(ps:现在的商业虚拟机都采用这种收集算法回收新生代,例如:SUN JDK1.3.1版本启用的HotSpot虚拟机)

标记整理算法: 标记整理算法主要分为算个阶段,首先将要清理的对象标记出来和标记清除的第一阶段一样,然后将有效的对象向一端移动(类似于我们有win7优化到时整理内存碎片的效果),最后将有效对象边界以外的对象全部回收掉。 优缺点:有点就是和标记清除算法相比减少了内存碎片,和复制算法相比提高内存利用率。 缺点:效率较低。

(3)常用的垃圾收集器:

  1. Serial收集器:单线程收集器,只会启动一条线程进行内存回收工作,在回收的过程中,必须暂停其他所有的工作线程。serial是一个比较原始的收集器,运行在Server端的JVM已经不再使用Serial,不过对于运行在Client端的JVM是一个很好的选择(单线程嘛,意味着没有线程切换开销)。Serial对于Yong区采用的是复制算法,对于Tenured采用的是标记整理算法。
  2. ParNew收集器: ParNew收集器是Serial收集器的多线程版本,对于收集算法以及控制参数Serial和ParNew一样,ParNew是运行在Server模式下的JVM的首选的新生代收集器,主要原因是除了ParNew能和Serial配合使用外,只有ParNew能和CMS协同工作。
  3. Parallel Scavenge收集器:多线程的新生代收集器,采用的复制算法,看上去和ParNew一样,但专注点不同,ParNew专注于在收集过程中缩短用户线程的停顿时间,而它专注于达到一个可控的吞吐量(吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间))。
  4. Serial Old收集器:Serial的老年代版本,采用的是标记整理算法,现在跑Server端JVM进程实例不经常使用的收集器,比较古老。
  5. Parallel Old收集器:Parallel Scavenge的老年代版本,使用多线程和标记-整理算法。Paralle Old出现之后就可以和Parallel Scavenge配合使用了。
  6. CMS收集器:CMS(Concurrent Mark Sweep)收集器是一种以获取最短停顿时间为目标的收集器,目前在市场上使用的占比很大。它是一款老年代收集器,采用的是标记-清除算法。它在清理过程中主要包含4个阶段,分别是初始标记,并发标记,重新标记,并发清除。其中只有初始标记和重新标记需要停顿用户线程,在并发标记和并发清除阶段,用户线程和回收器线程可以共同运行(将整个回收过程分成好多段,以达到减少停顿用户线程的目的)。
  7. G1收集器是JDK1.7提供的收集器,G1基于标记-整理算法(没有内存碎片),试用于新生代和老年代。它改变了收集的策略,不在针对新生代和老年代整个区域进行收集,而是把新生代或老年代划分成多个单元格,针对每个单元格的使用程度,对每个单元格进行收集,属于算法的优化和突破。

下面这个图不错的表达了各个收集器使用的分代区域: 

IV.JVM垃圾回收日志结构分析及常用的命令

我们在我们Server的gc log上经常看到下面的这个日志。 总结一下各个字段表达的是什么意思: Young GC: 

Full GC: 

相关文章:

开源库Simd在vs2010中的编译及简单使用

Simd是开源的图像处理库&#xff0c;它提供了很多高性能的算法&#xff0c;这些优化算法主要由SIMD指令来实现&#xff0c;包括SSE、SSE2、SSSE3、SSE4.1、SSE4.2、AVX等&#xff0c;此库可以应用在windows/linux 32bit/64bit等系统中。此库更新较频繁。此库的license是MIT。下…

Dubbo2.6.5+Nacos注册中心(代替Zookeeper)

在上一节的小栗子的基础上&#xff0c;只需要更改两个地方 第一个&#xff1a;父工程的pom依赖增加 <!-- Dubbo Nacos registry dependency --><dependency><groupId>com.alibaba</groupId><artifactId>dubbo-registry-nacos</artifactId>…

Nginx(二) 配置与调试

nginx 主配置文件在安装目录下的conf中&#xff0c;名字为nginx.conf&#xff1a;主配置文件主要分为4部分&#xff1a;main&#xff08;全局设置&#xff09;、server&#xff08;主机设置&#xff09;、upstream&#xff08;负载均衡服务器设置&#xff09;和location&#x…

AI编程语言图鉴

作者 | 元宵大师责编 | 胡巍巍来源 | CSDN&#xff08;CSDNnews&#xff09;当前最炙手可热的领域非“人工智能”&#xff08;Artificial Intelligence&#xff09;莫属。其实&#xff0c;“人工智能”的火热并非一蹴而就&#xff0c;早在1956年“人工智能”概念就已经被提出了…

C++动态二维数组演示的代码

将代码过程中经常用到的代码珍藏起来&#xff0c;下边资料是关于C动态二维数组演示的代码。 #include <iostream> #include <string>using namespace std;{for( int i 0; i < x; i ){List[i] new int[y];for( int j 0; j < y; j ){List[i][j] 0;}}for( i…

linux发送email错误 501 Syntax: HELO hostname

2019独角兽企业重金招聘Python工程师标准>>> 查看你的hostname hostnamecentos58 然后vi /etc/hosts 添加hostname对应的ip 103.24.3.171 centos58 参考http://blog.csdn.net/tammy_zhu/article/details/5563383 转载于:https://my.oschina.net/u/257088/bl…

redux-thunk使用教程

从无到有一步一步创建一个react-redux、redux-thunk使用教程&#xff1a;本教程GitHub地址&#xff1a;https://github.com/chunhuigao/react-redux-thunk创建react工程在电脑上找一个文件夹&#xff0c;在命令窗使用create-react-app 创建我的react工程&#xff1b;这一步应该…

VLC SDK在VS2010中的配置及简单使用举例

1. 从http://www.videolan.org/vlc/download-windows.html下载vlc-2.2.0-win32.7z&#xff0c;解压缩&#xff1b;2. 新建一个VLCtest控制台工程&#xff1b;3. 将/vlc-2.2.0-win32/vlc-2.2.0/sdk/include添加到工程属性中&#xff0c;C/C -->General …

百万奖金悬赏AI垃圾分类,就问你来不来?

也许我们从来没有想过&#xff0c;看似简单的垃圾分类居然给“聪明”的人类带来如此大的困扰2019年7月1日&#xff0c;史称“最严格的垃圾分类法”《上海市生活垃圾管理条例》正式开始施行一夜之间上海人最常用的见面语从“侬好”变成了“侬是什么垃圾&#xff1f;”虽然只有可…

资质申报 - 系统集成企业资质等级评定条件(2012年修定版)

关于发布《计算机信息系统集成企业资质等级评定条件&#xff08;2012年修定版&#xff09;》的通知工信计资&#xff3b;2012&#xff3d;6号各省、自治区、直辖市、计划单列市工业和信息化主管部门、新疆生产建设兵团工业和信息化委员会、各级资质评审机构&#xff0c;各有关单…

@HostListener 可接收的事件列表

下面有一个文档详细介绍Angular 中的事件列表&#xff1a; https://github.com/angular/angular/blob/master/packages/compiler/src/schema/dom_element_schema_registry.ts#L78。 星号代表的是事件 (no prefix): property is a string.*: property represents an event.!: pr…

GraphSAGE: GCN落地必读论文

作者 | William L. Hamilton, Rex Ying, Jure Leskovec来源 | NIPS17导读&#xff1a;图卷积网络&#xff08;Graph Convolutional Network&#xff0c;简称GCN&#xff09;最近两年大热&#xff0c;取得不少进展。作为 GNN 的重要分支之一&#xff0c;很多同学可能对它还是一知…

Ubuntu14.04 32位上编译VLC2.2.0源码操作步骤

1. 首先安装必须的依赖软件&#xff0c;打开终端&#xff0c;执行&#xff1a;sudo apt-get install git libtool build-essential pkg-config autoconf2. 从 http://www.videolan.org/vlc/download-sources.html 下载vlc-2.2.0源码&#xff0c;将其存放到/home/spring/VLC目录…

根据PromiseA+规范实现Promise

Promise是ES6出现的一个异步编程的一个解决方案&#xff0c;改善了以往回调函数的回调地狱(虽然写起来也挺像的)。不会Promise的可以移步阮一峰的Promise&#xff0c;这里讲的非常清晰。 就现在的发展情况而言&#xff0c;Promise这种解决方案频繁的在我们的代码中出现&#xf…

黄浴:基于深度学习的超分辨率图像技术发展轨迹一览

作者 | 黄浴转载自知乎导读&#xff1a;近年来&#xff0c;使用深度学习技术的图像超分辨率&#xff08;SR&#xff09;取得了显著进步。本文中&#xff0c;奇点汽车自动驾驶首席科学家黄浴对基于深度学习技术的图像超分辨率技术进行了一次全面的总结&#xff0c;分析了这门技术…

Qt简介、安装及在Ubuntu14.04 32位上简单使用举例

Qt是一个跨平台的C图形用户界面应用程序开发框架。它既可以开发GUI程序&#xff0c;也可用于开发非GUI程序。Qt是面向对象的框架&#xff0c;很容易扩展。Qt是一个C工具包&#xff0c;它由几百个C类构成&#xff0c;你在程序中可以使用这些类。Qt具有OOP的所有优点。 跨平台的…

FOSCommentBundle功能包:设置Doctrine ODM映射(投票)

原文出处&#xff1a;12b-mapping_mongodb.md原文作者&#xff1a;FriendsOfSymfony授权许可&#xff1a;创作共用协议翻译人员&#xff1a;FireHare校对人员&#xff1a;适用版本&#xff1a;FOSCommentBundle 2.0.5文章状态&#xff1a;草译阶段Step 12b: Setup MongoDB mapp…

Python最大堆排序实现方法

Python最大堆排序实现方法&#xff0c;具体代码如下&#xff1a; # -*- coding: utf-8 -*- def merge_sort(seq, cmpcmp, sentinelNone): """合并排序&#xff0c;伪码如下&#xff1a; MERGE(A, p, q, r) 1 n1 ← q - p 1 // 前个子序列长度 2 …

内含福利 | 世界人工智能大会:对话大咖,深挖机器学习的商业应用

机器学习作为人工智能时代的关键技术突破&#xff0c;已经在日常生活中广泛应用&#xff0c;给用户带来便利。越来越多的企业也通过机器学习&#xff0c;解决生产和经营中的难题。传统制造业&#xff1a;应用机器学习&#xff0c;部署系统异常检测方案&#xff0c;预测组件寿命…

windows7 64位操作系统上使vs2010和vs2013能够并存的处理方法

之前机子上是只安装有vs2010&#xff0c;后来在没有卸载vs2010的情况下想装个vs2013,使vs2010与vs2013同时并存在windows764位机上。需要依次安装cn_visual_studio_ultimate_2013_x86_dvd_3009109.iso、vs2013.2.iso和vc_mbcsmfc.exe。在安装过程中遇到的问题有&#xff1a; (…

Spring Cloud Alibaba 基础教程:Nacos 生产级版本 0.8.0

Spring Cloud Alibaba 基础教程&#xff1a;Nacos 生产级版本 0.8.0 昨晚Nacos社区发布了第一个生产级版本&#xff1a;0.8.0。由于该版本除了Bug修复之外&#xff0c;还提供了几个生产管理非常重要的特性&#xff0c;所以觉得还是有必要写一篇讲讲这次升级&#xff0c;在后续的…

awk命令使用和取出数据的最大值,最小值和平均值

得到取出数据的最大值&#xff1a;cat manager.txt |grep monitor|awk {print$9}|sort -rn|head -1得到取出数据的最小值&#xff1a;cat manager.txt|grep monitor |awk {print $9}|sort -n|head -1得到取出数据的平均值&#xff1a;cat manager.txt|grep monitor |awk {print…

windows7 64位机上CUDA7.0配置及在VS2010中的简单使用举例

1. 查看本机配置&#xff0c;查看显卡类型是否支持NVIDIA GPU&#xff0c;选中计算机--> 右键属性 --> 设备管理器 --> 显示适配器&#xff1a;NVIDIA GeForce GT 610&#xff0c;从https://developer.nvidia.com/cuda-gpus可以查到相应显卡的compute capabili…

用友云平台,真正的云原生架构,加速云应用落地

数字化经济的出现&#xff0c;企业需要通过新技术实现数字化转型&#xff0c;完成企业管理和业务模式变革。而云计算是数字化中尤为重要且能够更快实现的技术手段。真正的云应用必须是基于云原生架构的&#xff0c;PaaS是一个重要的步骤&#xff0c;因为这是云原生的第一接触点…

从ACM班、百度到亚马逊,深度学习大牛李沐的开挂人生

“大神”&#xff0c;是很多人对李沐的印象。作为一经推出便大受追捧的 MXNet 深度学习框架的主要贡献者之一&#xff0c;李沐功不可没。值得注意的是&#xff0c;这个由 DMLC&#xff08;Distributed Machine Learning Community&#xff09;打造的深度学习框架&#xff0c;创…

Linux基础介绍

Linux的创始人Linus Torvalds。Linux的官方标准发音为[linəks]。Linux和Unix是非常像的&#xff0c;Linux就是根据Unix演变过来的。Linux是免费的&#xff0c;其实只是说Linux的内核免费。在Linux内核的基础上产生了众多的Linux版本。Linux的发行版说简单点就是将Linux内核与应…

Go在区块链的发展和演进

Go语言发展至今已经过去十年多了&#xff0c;是目前最流行的新兴语言&#xff0c;云计算领域的首选语言&#xff0c;而且目前随着区块链的流行&#xff0c;Go再次成为了这个领域的第一语言&#xff0c;以太坊&#xff0c;IBM的fabric等重量级的区块链项目都是基于Go开发。 原文…

一天掌握AI核心技术,上手应用,开发者该划哪些重点?

Alpha Go 只会下棋&#xff0c;却并不擅长垃圾分类&#xff1b;智能助手已经可以执行很多任务&#xff0c;但距离真正的人机自然交互还很远。如今 AI 的发展面临着诸多瓶颈&#xff0c;基础理论研究缺失&#xff0c;深度学习的黑箱属性无解&#xff0c;把一切托付于未知并不可靠…

学会这21条,你离Vim大神就不远了

来源 | Python编程时光&#xff08;ID: Python-Time&#xff09;导语&#xff1a;作者本人是 Vim 的重度使用者&#xff0c;就因为喜欢上这种双手不离键盘就可以操控一切的feel&#xff0c;Vim 可以让人对文本的操作更加精准、高效。对于未使用过 Vim 的朋友来说&#xff0c;可…

C 语言 和 C++语言的对比学习   二 数据类型

不管是什么语言&#xff0c;我们最习惯的是通过 “hello world” &#xff0c;来昭告世界&#xff0c;我们有了新的语言来向这个世界问好&#xff0c;尽管真正属于我们自己的其实是哭声。&#xff08;呵呵&#xff0c;笑点有点低&#xff09;&#xff0c;下面我们来介绍最为基础…