JVM深入理解
java课的作业让我们深入理解一下JVM虚拟机,之前看过很多相关知识,都容易忘掉,这里对最近学习到的知识做一下总结:
JVM简介
JVM的基本结构一般如下图所示:
每个JVM有两种机制,一个是类装载子系统,一个是负责执行包含在已装载类中的指令,称为执行引擎。每个JVM又包括方法区(method area)、堆(heap)、虚拟机栈(VM Stack)、程序计数器(PC Register)和本地方法栈(native stack)这五个部分:
方法区:用于存储类结构信息的地方,包括常量池、静态变量、构造函数等。方法区存放装载的类数据信息包括:
- 基本信息:
- 每个类的全限定名。
- 每个类的直接超类的全限定名(可约束类型转换)。
- 该类是类还是接口。
- 该类型的访问修饰符。
- 直接超接口的全限定名的有序列表。
每个已装载类的详细信息:
运行时常量池:存放该类型所用的一切常量,它们以数组形式通过索引被访问,是外部调用与类联系及类型对象化的桥梁。它是类文件(字节码)常量池的运行时表示。
字段信息:类中声明的每一个字段的信息(名,类型,修饰符)。
方法信息:类中声明的每一个方法的信息
静态变量
到类classloader的引用:即到该类的类装载器的引用。
到类class的引用:虚拟机为每一个被装载的类型创建一个class实例,用来代表这个被装载的类。
方法表:虚拟机对每个装载的非抽象类,都生成一个方法表,把它作为类信息的一部分保存在方法区。方法表是一个数组,它的元素是所有它的实例可能被调用的实例方法的直接引用,包括那些从超类继承过来的实例方法。
堆(Heap):存储java实例或者对象的地方。从存储的内容我们可以很容易知道,方法区和堆是被所有java线程共享的。
虚拟机栈:每当创建一个线程时,JVM就会为这个线程创建一个对应的虚拟机栈。每运行一个方法就会创建一个栈帧,用于存储局部变量表、操作栈、方法返回值等。每一个方法从调用直至执行完成,就对应一个栈帧在虚拟机栈中入栈到出栈的过程。所以虚拟机栈是线程私有的。
程序计数器:用于保存当前线程执行的内存地址,记录线程中断的地方,线程私有。
本地方法栈:和虚拟机栈的作用差不多,只不过是为JVM的native方法服务,线程私有
内存分配
java内存分配一般有两种:静态内存和动态内存。很容易理解,编译时就能够确定的内存就是静态内存,即内存是固定的,系统一次性分配,比如int类型变量;动态内存分配就是在程序执行时才知道要分配的存储空间大小,比如java对象的内存空间。根据上面我们知道,java栈、程序计数器、本地方法栈都是线程私有的,栈中的栈帧随着方法的结束会撤销,内存自然就跟着回收了。所以这几个区域的内存分配与回收是确定的。但是堆和方法区则不一样,我们只有在程序运行期间才知道会创建哪些对象,所以这部分内存的分配和回收都是动态的。一般我们所说的垃圾回收也是针对的这一部分。
垃圾检测、回收算法
检测垃圾:引用计数法(无法回收循环指向的内存),可达性分析算法(精度高效率低)
回收算法:
标记-清除(mark-sweep):效率低,会产生大量碎片
复制(Copying):不会出现内存问题,需要两倍内存空间
标记-整理(mark-compact):第一步标记被引用的对象,第二步清除未被引用的对象,并把存活的对象压缩到一块
增量收集:基础仍是传统的标记-清除和复制算法。增量收集算法通过对进程间冲突的妥善处理,允许垃圾收集进程以分阶段的方式完成标记、清理或复制工作。实时垃圾收集的梦想变成了现实,再也不用为垃圾收集打断程序的运行而烦恼了。增量收集算法比较典型的是火车算法,它是为了在成熟对象空间提供限度时间的增量收集。
分代收集:年轻的和年老的,垃圾收集器使用不同的收集算法来处理这两类内存块。
垃圾收集器
主要有serial,ParNew,Parallel Scavenge,Serial Old,Parallel Old, CMS,G1这些。
详细可以参考这篇博文http://blog.csdn.net/java2000_wl/article/details/8030172
G1收集器目前已在jdk1.9中默认使用了,将堆分成多个region,基于标记-整理收集垃圾,标记过程分五个阶段,大部分都是并发执行,大大提高了的速度。
FTP安装
最近突然想到自己的学生优惠还没有用,赶紧在京东云上购买了一个便宜的云主机,以备后用,顺便把linux上的知识复习一下,都快忘光了。
云主机系统为ubuntu 16.04 (命令:head -n 1 /etc/issue)
硬件信息 uname -a
之后又安装了一下nodejs,npm等要用到的软件
sudo apt-get install nodejs
sudo apt-get install npm
之后就是安装FTP服务器的过程了
sudo apt-get update
sudo apt-get install vsftpd
update是为了防止有些包安装不上,以防意外。在安装好vsftpd后,我们可以通过
service vsftpd start # 启动服务
service vsftpd status # 查看服务状态
按照网上有些资料的说法是,安装好vsftpd后会在home目录下生成一个ftp文件夹,然而我的主机上并没有,只能搜索一下再操作了:
find / -name ftp -type d # 搜索名为ftp的文件夹
mkdir public # 创建个public 文件夹
chmod 777 public
准备工作完成,再修改一下vsftpd的配置文件(/etc/vsftpd.conf),这里为了能尽快上传文件,启用了如下几行:
anonymous_enable=YES
anon_upload_enable=YES
anon_mkdir_write_enable=YES
local_enable=YES
write_enable=YES
local_umask=022
更多配置可以参考京东云的官方文档
本来以为这样就可以大功告成了,结果在本机windows这边连接ftp的过程中遇上了一些问题,主要是“无法访问FTP服务器,没有权限”等等。考虑到时客户端这边的问题,先检查FTP服务是否已经打开,控制面板-》程序-》启用或关闭windows功能-》Internet Information Services-》FTP服务器,全部启用,之后在去Internet选项中,在设置-》高级中禁用掉“使用被动FTP”。
这两项操作完成后,我的问题就解决了。随后可以正常匿名访问FTP了,于是直接复制文件过去,结果发现又报错了,500:unknown command。
检查服务器的文件夹发现,大部分小文件都发过去了,只有图片传不过去,所以这里我选择先在windows上压缩成zip格式文件,再复制到服务器,之后在服务器上解压即可。
sudo apt-get install zip
unzip myfile.zip
接下来就可以愉快的玩主机了,把忘掉的命令都捡起来。
常用指令
nginx配置
nginx的安装不用多言,其中要用到的PCRE库、zlib库、OpenSSL库的下载安装可以参考这篇博客
在配置过程中参考了很多博文,比较杂乱无章,这里我的配置如下:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 768;# multi_accept on;
}
http {## # Basic Settings ## sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; # server_tokens off; # server_names_hash_bucket_size 64; # server_name_in_redirect off; include /etc/nginx/mime.types; default_type application/octet-stream; ## # SSL Settings ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE ssl_prefer_server_ciphers on; ## # Logging Settings ## access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; ## # Gzip Settings ## gzip on; gzip_disable "msie6"; # gzip_vary on; # gzip_proxied any; # gzip_comp_level 6; # gzip_buffers 16 8k; # gzip_http_version 1.1; # 添加一个服务配置,访问域名,从而跳转到服务器地址 server { listen 80; server_name 域名; location / { root 资源文件; proxy_connect_timeout 3; proxy_send_timeout 30; proxy_read_timeout 30; proxy_pass http://localhost:3000; # 重定向的地址 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } # 图片资源访问不到,在这里添加图片资源路径 location ~ .*\.(gif|jpg|jpeg|png)$ { expires 24h; root assets; # 资源地址 proxy_store on; proxy_store_access user:rw group:rw all:rw; proxy_redirect off; proxy_set_header Host localhost; client_max_body_size 10m; client_body_buffer_size 1280k; proxy_connect_timeout 900; proxy_send_timeout 900; proxy_read_timeout 900; proxy_buffer_size 40k; proxy_buffers 40 320k; proxy_temp_file_write_size 640k; } } ## # Virtual Host Configs ## include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*;
}