前言
Java8(又称为 Jdk1.8)是 Java 语言开发的一个主要版本。Oracle 公司于 2014 年 3 月 18 日发布 Java8,它支持函数式编程,新的 JavaScript 引擎,新的日期 API,新的 Stream API 等。Java8 API 添加了一个新的抽象称为流 Stream,可以让你以一种声明的方式处理数据。Stream API 可以极大提高 Java 程序员的生产力,让程序员写出高效率、干净、简洁的代码。
趁着年轻,好好生活,用心折腾。
JVM 的内存模型是 Java 语言绕不开的一个话题。对于 Java 程序员来说,在虚拟机自动内存管理机制的帮助下,不再需要为每一个 new 操作去写配对的 delete/free 代码,不容易出现内存泄漏问题,由虚拟机管理内存这一切看起来都很美好。不过,也正因为 Java 程序员把内存控制的权利交给了 Java 虚拟机,一旦出现内存泄漏和溢出方面的问题,如果不了解虚拟机是怎样使用内存的,那么排查错误将成为一项异常艰难的工作。即要进行 Java 的性能调优,首先就要了解其内存模型;同时,在诸多的面试笔试中,这也是很多面试官会考察的内容。
本篇是我学习 JVM 系列的开篇,同时也是我阅读周志明老师《深入理解 Java 虚拟机》一书的学习笔记,主要内容讲述 JVM 的基本概念,然后从概念上介绍 Java 虚拟机内存的各个区域,讲解这些区域的作用、服务对象以及其中可能产生的问题,最后讨论一下常见的内存泄漏和溢出的问题。
在我们打开 Linux 电脑的电源后第一个启动的进程就是 init。分配给 init 进程的 PID 是 1。它是系统其他所有进程的父进程。当一台 Linux 电脑启动后,处理器会先在系统存储中查找 BIOS,之后 BIOS 会检测系统资源然后找到第一个引导设备,通常为硬盘,然后会查找硬盘的主引导记录(MBR),然后加载到内存中并把控制权交给它,以后的启动过程就由 MBR 控制。
主引导记录会初始化引导程序(Linux 上有两个著名的引导程序,GRUB 和 LILO,80% 的 Linux 系统在用 GRUB 引导程序),这个时候 GRUB 或 LILO 会加载内核模块。内核会马上查找 / sbin 下的 “init” 程序并执行它。从这里开始 init 成为了 Linux 系统的父进程。init 读取的第一个文件是 / etc/inittab,通过它 init 会确定我们 Linux 操作系统的运行级别。它会从文件 / etc/fstab 里查找分区表信息然后做相应的挂载。然后 init 会启动 / etc/init.d 里指定的默认启动级别的所有服务 / 脚本。所有服务在这里通过 init 一个一个被初始化。在这个过程里,init 每次只启动一个服务,所有服务 / 守护进程都在后台执行并由 init 来管理。
关机过程差不多是相反的过程,首先 init 停止所有服务,最后阶段会卸载文件系统。
以上提到的启动过程有一些不足的地方:一是启动时间长。init 进程是串行启动,只有前一个进程启动完,才会启动下一个进程;二是启动脚本复杂。init 进程只是执行启动脚本,不管其他事情。脚本需要自己处理各种情况,这往往使得脚本变得很长。而用一种更好的方式来替代传统 init 的需求已经存在很长时间了。也产生了许多替代方案。其中比较著名的有 Upstart,Epoch,Muda 和 Systemd。而 Systemd 获得最多关注并被认为是目前最佳的方案。
Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.