一次Java进程物理内存占用超过最大堆内存分析
一、背景说明项目测试过程中,测试人员反馈使用Excel导入100万号码时报错,通过Top命令查看到该java进程占用物理内存大小为3.4G,而且内存持续占用,一直没有释放,怀疑是不是有内存泄露的情况。
PS:上图为后续重新截的图,比第一次物理内存占用小
JVM配置参数如下:
server.java.opts=-d64 -XX:MaxPermSize=192M -Xms3000M -Xmx3000M -XX:+HeapDumpOnOutOfMemoryError
二、问题排查查看日志发现出现了OOM, 报错信息未:java.lang.OutOfMemoryError: GC overhead limit exceeded,并生成了堆内存快照文件java_pid31734.hprof。通过jVisualVM工具分析java_pid31734.hprof文件。
java进程发生OOM时生成的堆内存快照文件大小为3.4G。
由于在项目中使用POI去读取Excel文件的,从内存快照中可以看到大量的内存被POI相关的对象占用。
发生OOM后java进程并没有退出,仍可 ...
RocketMQ设计原理分析
RocketMQ设计原理分析——技术分享PPT
突然消失的Java进程
一、背景说明在一次大批量数据测试时,一个Java服务模块突然宕掉,并且连续出现了好几次。检查服务已经开启了打印堆栈信息-XX:+HeapDumpOnOutOfMemoryError,但是在服务器运行目录下并没有发现.hprof文件生成。服务器总内存为16G,当前Java服务设置的内存为:-Xms5000M -Xmx8000M。
二、原因分析Java进程突然被干掉无外乎以下三种情况:
Linux OOM killer 杀死了Java进程
JVM自身故障
JVM OOM导致进程退出
2.1 Linux 的OOM killerLinux内核有一个OOM(out of memory) killer机制,当系统内存严重不足时,OOM killer会选择一个或多个进程杀死。关于OOM killer机制可参考上一篇文章Linux中的CommitLimit与OOM Killer.。因此,当java进程突然消失时,首先怀疑是不是被OOM killer杀掉了。
查看系统日志文件/var/log/messages
$egrep -i 'killed process' /va ...
Linux中的CommitLimit与OOM Killer
一、背景说明在测试过程中遇到一个Java进程由于申请内存过大导致被Linux OOM killer杀掉的问题,所以来分析一下Linux中的CommitLimit与OMM killer机制。
二、Linux内存分配机制 Linux系统允许程序申请比系统可用内存更多的内存空间,这个特性叫做 overcommit 特性,这样做可能是为了系统的优化,因为不是所有的程序申请了内存就会立刻使用,当真正的使用时,系统可能已经回收了一些内存。为了避免内存的浪费,在分配页面时,Linux 采用的是按需分配物理页面的方式。譬如说,某个进程调用malloc()申请了一块小内存,这时内核会分配一个虚拟页面,但这个页面不会映射到实际的物理页面。从图中可以看到,当程序首次访问这个虚拟页面时,会触发一个缺页异常 (page fault)。这时内核会分配一个物理页面,让虚拟页面映射到这个物理页面,同时更新进程的页表 (page table)。
2.1 Linux的Memory Overcommit这种按需分配物理页面的方式,可以大大节省物理内存的使用,但有时会导致 Memory Overcommit。所谓 Memo ...
RocketMQ中Mmap原理分析及使用
一、Mmap基础概念Mmap是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动回写脏页面到对应的文件磁盘上,即完成了对文件的操作而不必再调用read,write等系统调用函数。相反,内核空间对这段区域的修改也直接反映用户空间,从而可以实现不同进程间的文件共享。
二、Mmap内存映射原理
mmap内存映射的实现过程,总的来说可以分为三个阶段:
(一)进程启动映射过程,并在虚拟地址空间中为映射创建虚拟映射区域
1、进程在用户空间调用库函数mmap,原型:void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
2、在当前进程的虚拟地址空间中,寻找一段空闲的满足要求的连续的虚拟地址
3、为此虚拟区分配一个vm_area_struct结构,接着对这个结构的各个域进行了初始化
4、将新建的虚拟区结构(vm_area_stru ...
RocketMQ消息存储
一、消息存储架构图
二、消息存储2.1 消息存储文件
文件名称
作用
文件大小
文件格式
说明
CommitLog
消息主体以及元数据的存储主体
单个文件大小默认1G
消息顺序写入文件,当文件满了,写入下一个文件
文件名为20位,如一个文件名为00000000000000000000代表以一个文件,起始偏移量为0,文件大小为1G=1073741824,后面新增文件的名称基于上一个文件名累加1G,起始偏移量从上一个文件继续累计。
ConsumeQueue
消息消费队列
每个条目20个字节,单个文件由30W个条目组成
每一个条目共20个字节,分别为8字节的commitlog物理偏移量、4字节的消息长度、8字节tag hashcode
单个文件由30W个条目组成,可以像数组一样随机访问每一个条目,每个ConsumeQueue文件大小约5.72M
IndexFile
索引文件
固定的单个IndexFile文件大小约为400M,一个IndexFile可以保存 2000W个索引
IndexFile的底层存储设计为在文件系统中实现HashMap结构
rocketmq的索引文件其底层 ...
Nginx代理配置中的DNS缓存问题
一、问题背景客户内网环境不允许应用服务器直接访问外网,必须通过跳板机访问外网,所在使用Nginx代理访问外网,部署架构图可参考Nginx反向代理HTTP header自定义参数丢失问题。在部署完成后,测试代理接口都正常,但是一段时间过后,就出现了外网接口访问超时的问题。
二、问题排查Nginx代理的外网接口都是通过域名进行访问,发现请求超时后,直接在服务器上ping请求地址中的域名,发现域名是可以ping通的,后面继续观察请求超时的情况,发现每次出现请求超时时,在服务器都是能直接ping通请求中的域名,但是服务器每次ping命令解析后的IP与上一次不同,在服务器则无法ping通上次解析后的IP,所以怀疑是不是Nginx缓存了DNS解析。通过查阅文档,发现Nginx在启动时会检查域名是否能够解析,在第一次请求时会缓存DNS解析记录,并且忽略了DNS中的TTL值永久缓存。
注意:在使用Nginx进行反向代理时,如果配置的是域名,突然出现了404问题时,可以查看域名绑定的IP是否发生了变更,如果这种变更不频繁,可以重启Nginx解决,重启Nginx后域名会重新进行解析。
三、问题分析与解 ...
Nginx反向代理HTTP header自定义参数丢失问题
一、问题背景客户内网服务器不能直接访问外网,需要通过一台跳板机才能访问外网,在跳板机安装Nginx反向代理外网接口服务,架构图如下:代理设置完成后,在联调过程中请求外网接口返回参数错误,但是外网环境下不经过Nginx代理直接访问外网接口则能正常访问,说明在经过Nginx代理时,部分参数丢失了。
二、问题排查根据接口报错,定位到是HTTPheader中的一个自定义参数client_id参数经过Nginx代理时没有转发出去,问题出现在Nginx代理上。
Nginx主配置文件nginx.conf内容如下
user root;
worker_processes 1;
error_log logs/error.log;
error_log logs/error.log notice;
error_log logs/error.log info;
pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
...
Nginx反向代理404问题
一、问题背景 在测试web应用的时候,前端需要进行跨域访问后端接口,由于服务端跨域访问功能不完善,所以打算通过反向代理临时解决跨域问题,但是反向代理配置成功后,访问时浏览器端返回404,在nginx的访问日志中也提示404,Nginx配置如下。
1.1 Nginx反向代理配置server {
listen 80;
server_name h5-verify.mpoom.cn;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8000;
}
}
server {
listen 8 ...
Java 和 HTTP 的那些事(四) HTTPS 和 证书
非原创,转载于:https://www.aneasystone.com/archives/2016/04/java-and-https.html
说起 HTTP 的那些事,则不得不提 HTTPS ,而说起 HTTPS ,则不得不提数字证书。这篇博客将从 Java 的角度,学习 HTTPS 和数字证书技术,并分享爬虫开发的过程中针对爬取 HTTPS 站点时可能遇到的一些问题。在前面的几篇博客里,其实已经略微提到过 HTTPS 了,譬如使用 HttpsURLConnection 类发送 HTTPS 请求,在使用代理时 HTTP 和 HTTPS 的一些差异等等。关于 HTTPS 的概念就不废话了,下面直接进入正题。
一、访问 HTTPS 站点在前面的第一篇博客《模拟 HTTP 请求》里,介绍了两种方法来模拟发送 HTTP 请求,访问 HTTP 站点。一种方式是通过 java.net 自带的 HttpURLConnection,另一种方式是通过 Apache 的 HttpClient,这两种方式各有各的优势。这里也使用这两种方式来访问 HTTPS 站点,从下面的代码可以看到,和前面访问 H ...