Diagnosing out of memory errors and memory leaks 内存泄露实例 C Java JavaScript 内存泄露
小结:
1、
数据库连接池。
JDBC语句和结果对象必须显式地关闭。
2、
电梯到目标楼层后地址是否被释放
When a button is pressed:
Get some memory, which will be used to remember the floor number
Put the floor number into the memory
Are we already on the target floor?
If so, we have nothing to do: finished
Otherwise:
Wait until the lift is idle
Go to the required floor
Release the memory we used to remember the floor number
3、
指针不存在了,以分配的地址不能被释放,内存泄露发生
#include <stdlib.h> void function_which_allocates(void) {
/* allocate an array of 45 floats */
float *a = malloc(sizeof(float) * 45); /* additional code making use of 'a' */ /* return to main, having forgotten to free the memory we malloc'd */
} int main(void) {
function_which_allocates(); /* the pointer 'a' no longer exists, and therefore cannot be freed,
but the memory is still allocated. a leak has occurred. */
}
4、页面文件-主内存
内存分配是动态的——每个进程根据要求获得相应的内存。访问活跃的页面文件被转移到主内存以提高访问速度;反之,访问不活跃的页面文件被转移到次级存储设备。
One example of memory leak is when using database connection pools in application server. When using connection pools, the JDBC statement and resultset objects must be explicitly closed in a finally block. This is due to the fact that calling close() on the connection objects from pool will simply return the connection back to the pool for re-use and it doesn’t actually close the connection and the associated statement/resultset objects.
It is recommended to follow the coding practices suggested in the following documents to avoid memory leaks in your application.
JDBC – Closing JDBC Objects
JNDI – Closing the Context
JMS – Releasing Object Resources
Diagnosing out of memory errors and memory leaks
BY RAMAKANTA · PUBLISHED JULY 29, 2012 · UPDATED MARCH 26, 2015
Before we go for the debug we shall know what are Java heap, Native memory and Process size.
Java heap
This is the memory that the JVM uses to allocate java objects. The maximum value of java heap memory is specified using the -Xmx flag in the java command line. If the maximum heap size is not specified, then the limit is decided by the JVM considering factors like the amount of physical memory in the machine and the amount of free memory available at that moment. It is always recommended to specify the max java heap value.
Native memory
This is the memory that the JVM uses for its own internal operations. The amount of native memory heap that will be used by the JVM depends on the amount of code generated, threads created, memory used during GC for keeping java object information and temporary space used during code generation, optimization etc.
If there is a third party native module, it could also use the native memory. For example, native JDBC drivers allocate native memory.
The max amount of native memory is limited by the virtual process size limitation on any given OS and the amount of memory already committed for the java heap with -Xmx flag. For example, if the application can allocate a total of 3 GB and if the max java heap is 1 GB, then the max possible native memory is approximately 2 GB.
Process size
Process size will be the sum of the java heap, native memory and the memory occupied by the loaded executables and libraries. On 32-bit operating systems, the virtual address space of a process can go up to 4 GB. Out of this 4 GB, the OS kernel reserves some part for itself (typically 1 – 2 GB). The remaining is available for the application.
Out of memory in java heap
The JVM throws java out of memory (java OOM) error if it is not able get more memory in java heap to allocate more java objects. The JVM cannot allocate more java objects if the java heap is full of live objects and it is not able to expand the java heap anymore.
In this situation, the JVM lets the application decide on what to do after throwing the java.lang.OutOfMemoryError. For example, the application may handle this error and decide to shut down itself in a safe way or decide to run ignoring this error. If the application doesn’t handle this error, then the thread that throws this error will exit (you will not see this thread if you take a java thread dump).
In the case of WebLogic Server, this error is handled if it is thrown by an execute thread and the error is logged. If this error is being thrown continuously, then the core health monitor thread shuts down WebLogic Server.
Out of memory in native heap
The JVM throws native out of memory (native OOM) if it is not able to get any more native memory. This usually happens when the process reaches the process size limitation on that OS or the machine runs out of RAM and swap space.
When this happens, the JVM handles the native OOM condition, logs a message saying that it ran out of native memory or unable to acquire memory and exits. If the JVM or any other loaded module (like libc or a third party module) doesn’t handle this native OOM situation, then the OS will send a sigabort signal to the JVM which will make the JVM exit. Usually, the JVMs will generate a core file when it gets a sigabort signal.
Determining whether OOM is a Java OOM or Native OOM
If the stdout/stderr message says that this is a java.lang.OutOfMemoryError, then this is a Java OOM.
If the stdout/stderr message says that it failed to acquire memory, then this is a Native OOM.
Please note that the above messages go to stdout or stderr and not to the application-specific log files like weblogic.log.
For Java OOM:
Collect and analyze the verbose garbage collection (GC) output.
Enable verbose GC logging. In order for GC activity to be efficiently logged, the following options should be included in the JVM upon start up:
For HotSpot: -verbose:gc, -XX:+PrintGCDetails, and -XX:+PrintGCTimeStamps. Xloggc: could also be specified to redirect the GC detailed stats to an output file. Itâs important to understand that the overhead for basic GC is null except for some disk space consumed by the log file (See Java HotSpot VM Options for more details).
For JRockit: -Xverbose:gc,gcpause,memdbg (See JRockit Command-Line Options for more details).
Make sure that the JVM does the following before throwing java OOM
Full GC run:
Does a full GC and all the un-reachable, phantomly, weakly and softly reachable objects are removed and those spaces are reclaimed. More details on different levels of object reachability can be found at: .
You can check whether full GC was done before the OOM message. A message like the following is printed when a full GC is done (format varies depending on the JVM: Check JVM help message to understand the format)
[memory ] 7.160: GC 131072K->130052K (131072K) in 1057.359 ms
The format of the above output follows (Note: the same format will be used throughout this Pattern):
[memory ] <start>: GC <before>K-><after>K (<heap>K), <total> ms
[memory ] <start> - start time of collection (seconds since jvm start)
[memory ] <before> - memory used by objects before collection (KB)
[memory ] <after> - memory used by objects after collection (KB)
[memory ] <heap> - size of heap after collection (KB)
[memory ] <total> - total time of collection (milliseconds)
However, there is no way to conclude whether the soft/weak/phantomly reachable objects are removed using the verbose messages. If you suspect that these objects are still around when OOM was thrown, contact the JVM vendor.
If the garbage collection algorithm is a generational algorithm (gencopy or gencon in case of Jrockit and the default algorithm in case of other JDKs), you will also see verbose output something like this:
[memory ] 2.414: Nursery GC 31000K->20760K (75776K), 0.469 ms
The above is the nursery GC (or young GC) cycle which will promote live objects from nursery (or young space) to old space. This cycle is not important for our analysis. More details on generational algorithms can be found in JVM documentation.
If the GC cycle doesn’t happen before java OOM, then it is a JVM bug.
Full compaction:
Make sure that the JVM does proper compaction work and the memory is not fragmented which could prevent large objects being allocated and trigger a java OOM error.
Java objects need the memory to be contiguous. If the available free memory is fragmented, then the JVM will not be able to allocate a large object, as it may not fit in any of the available free chunks. In this case, the JVM should do a full compaction so that more contiguous free memory can be formed to accommodate large objects.
Compaction work involves moving of objects (data) from one place to another in the java heap memory and updating the references to those objects to point to the new location. JVMs may not compact all the objects unless there is a need. This is to reduce the pause time of GC cycle.
We can check whether the java OOM is due to fragmentation by analyzing the verbose gc messages. If you see output similar to the following where the OOM is being thrown even whether there is free java heap available, then it is due to fragmentation.
[memory ] 8.162: GC 73043K->72989K (131072K) in 12.938 ms
[memory ] 8.172: GC 72989K->72905K (131072K) in 12.000 ms
[memory ] 8.182: GC 72905K->72580K (131072K) in 13.509 ms
java.lang.OutOfMemoryError
In the above case you can see that the max heap specified was 128MB and the JVM threw OOM when the actual memory usage is only 72580K. The heap usage is only 55%. Therefore, the effect of fragmentation in this case is to throw an OOM even when there is 45% of free heap. This is a JVM bug or limitation. You should contact the JVM vendor.
If the JVM does its work properly (all the things mentioned in the above step), then the java OOM could be an application issue. The application might be leaking some java memory constantly, which may cause this problem. Or, the application uses more live objects and it needs more java heap memory. The following things can be checked in the application:
Caching in the application – If the application caches java objects in memory, then we should make sure that this cache is not growing constantly. There should be a limit for the number of objects in the cache. We can try reducing this limit to see if it reduces the java heap usage.
Java soft references can also be used for data caching as softly reachable objects are guaranteed to be removed when the JVM runs out of java heap.
Long living objects
– If there are long living objects in the application, then we can try reducing the life of the objects if possible. For example, tuning HTTP session timeout will help in reclaiming the idle session objects faster.
Memory leaks
:One example of memory leak is when using database connection pools in application server. When using connection pools, the JDBC statement and resultset objects must be explicitly closed in a finally block. This is due to the fact that calling close() on the connection objects from pool will simply return the connection back to the pool for re-use and it doesn’t actually close the connection and the associated statement/resultset objects.
It is recommended to follow the coding practices suggested in the following documents to avoid memory leaks in your application.
JDBC – Closing JDBC Objects
JNDI – Closing the Context
JMS – Releasing Object Resources
Increase the java heap
– We can also try increasing the java heap if possible to see whether that solves the problem.
Workaround – As a temporary workaround, the application may be gracefully re-started when the java heap usage goes about 90%. When following this workaround, the java max heap can be set to as high as possible so that the application will take more time to fill all the java heap. The java heap usage can be monitored by adding the ‘-verbosegc’ flag (see above) in the java command line which will send the GC/heap usage info to stdout or stderr.
If none of the above suggestions is applicable to the application, then we need to use a JVMPI (JVM Profiler Interface) based profiler to find out which objects are occupying the java heap. The profilers also give details on the place in the java code from where these objects are being created. This document doesn’t cover the details on each profiler. Refer to the profiler documentation to understand how to set and start the application with this profilers. In general, JVMPI based profilers have high overhead and drastically reduce the performance of the application. Therefore, it is not advisable to use these profilers in production environments. A number of open source profilers can be explored from this site.
For Native OOM Problem
Collect the following information:
Enable verbose GC logging (see above) to monitor the java heap usage. This will help to understand the java memory requirement for this application.
It should be noted that independent of the actual java heap usage by the application, the amount of max heap specified (using -Xmx flag in the java command line) is reserved at the JVM startup and this reserved memory is not available for any other purpose.
In the case of JRockit, use -verbose instead of -verbosegc as this gives codegen information in addition to GC information.
Record the process virtual memory size periodically from the time the application was started until the JVM runs out of native memory. This will help to understand whether the process really hits the size limitation on that OS.
In case of Windows, use the following procedure to monitor the virtual process size:
In the Start -> Run... dialog, enter "perfmon" and click OK.
In the "Performance" window that pops up, click on the '+' button (above the graph).
Select the following options in the resulting Add Counters dialog:
Performance object: Process (not the default Processor)
Select counter from list: Virtual Bytes
Select instances from list: Select the JVM (java) instance
Click "Add", then "Close"
In case of Unix or Linux, for a given PID, the virtual memory size can be found using this command: ps -p <PID> -o vsz.
In the Linux case, each java thread within a single JVM instance is shown as a separate process. It is enough if we take the PID of the root java process. The root java process can be found using the –forest option for the ps command. For example, ps -lU <user> –forest will give a ASCII tree art for all the processes started by the specified user. You can find the root java from the tree art.
Memory availability in the machine
If the machine doesn’t have enough RAM and swap space, then the OS will not be able to give more memory to this process, and that could also result in out of memory. Make sure that the sum of RAM and swap space in the disk is sufficient to cater to all the running processes in that machine.
Tuning the java heap
If the java heap usage is well within the max heap, then reducing the java max heap will give more native memory to the JVM. This is not a solution but a workaround that can be tried. Since the OS limits the process size, we need to strike a balance between the java heap and the native heap.
Third party native modules or JNI code in the application
Check whether you are using any third-party native module like database drivers. These native modules could also allocate native memory and the leak may be from these modules. In order to narrow down the problem, you should attempt to reproduce the problem without these third-party modules. For example, you can use pure java drivers instead of native database drivers.
Check whether your application uses some JNI code. This could also be causing native memory leak and you can try to run the application without the JNI code if possible.
If the source of native memory cannot be found after the above steps, then you need to work with the JVM vendor to get a special build which can trace the native memory allocation calls and give more information about the leak.
https://en.wikipedia.org/wiki/Memory_leak
Diagnosing out of memory errors and memory leaks 内存泄露实例 C Java JavaScript 内存泄露的更多相关文章
- magento 2 Check https://getcomposer.org/doc/articles/troubleshooting.md#memory-limit-errors for more info on how to handle out of memory errors.%
Check https://getcomposer.org/doc/articles/troubleshooting.md#memory-limit-errors for more info on h ...
- Avoiding memory leaks in POSIX thread programming, 多线程避免内存泄漏
默认创建的线程为joinable的,必须调用pthread_join()才可以释放所占的内存 创建分离线程detach, attr 线程函数运行结束,调用pthread_exit 其它线程调用pthr ...
- Java 堆内存与栈内存异同(Java Heap Memory vs Stack Memory Difference)
--reference Java Heap Memory vs Stack Memory Difference 在数据结构中,堆和栈可以说是两种最基础的数据结构,而Java中的栈内存空间和堆内存空间有 ...
- MEMORY Storage Engine MEMORY Tables TEMPORARY TABLE max_heap_table_size
http://dev.mysql.com/doc/refman/5.7/en/create-table.html You can use the TEMPORARY keyword when crea ...
- Arcgis map export or print Error: Cannot map metafile into memory. Not enough memory
Arcgis map export or print Error: Cannot map metafile into memory. Not enough memory Link: https:/ ...
- #define barrier() __asm__ __volatile__("": : :"memory") 中的memory是gcc的东西
gcc内嵌汇编简介 在内嵌汇编中,可以将C语言表达式指定为汇编指令的操作数,而且不用去管如何将C语言表达式的值读入哪个寄存器,以及如何将计算结果写回C 变量,你只要告诉程序中C语言表达式与汇编指令操作 ...
- [Android Memory] 使用 Eclipse Memory Analyzer 进行堆转储文件分析
转载地址:http://www.ibm.com/developerworks/cn/opensource/os-cn-ecl-ma/index.html Eclipse Memory Analyzer ...
- 每个内存大小:sudo dmidecode -t memory |grep -A16 "Memory Device$" |grep "Size:"
CPU: 型号:grep "model name" /proc/cpuinfo |awk -F ':' '{print $NF}' 数量:lscpu |grep "CPU ...
- Tomcat 9内存溢出:"http-apr-8080-Acceptor-0" java.lang.OutOfMemoryError: Direct buffer memory
Tomcat开启了APR模式,而APR模式会使用堆外内存,关于堆内存可从如下链接了解一下:http://blog.csdn.net/zhouhl_cn/article/details/6573213. ...
随机推荐
- Shell脚本编程(一):初识shell script
Shell简介 Shell是一个命令解释器,它是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁.Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核 ...
- Python--Redis实战:第四章:数据安全与性能保障:第7节:非事务型流水线
之前章节首次介绍multi和exec的时候讨论过它们的”事务“性质:被multi和exec包裹的命令在执行时不会被其他客户端打扰.而使用事务的其中一个好处就是底层的客户端会通过使用流水线来提高事务执行 ...
- linux每日命令(11):cat命令
cat命令的用途是连接文件或标准输入并打印.这个命令常用来显示文件内容,或者将几个文件连接起来显示,或者从标准输入读取内容并显示,它常与重定向符号配合使用. 一.命令格式: cat [参数] [文件] ...
- Pitch detection algorithm(基音搜索算法)PDA相关链接
第一:维基百科 http://en.wikipedia.org/wiki/Pitch_estimation 简要系统介绍了基音估计算法的分类和一些链接,论文 第二:http://ws2.bingham ...
- MXNET:深度学习计算-GPU
mxnet的设备管理 MXNet 使用 context 来指定用来存储和计算的设备,例如可以是 CPU 或者 GPU.默认情况下,MXNet 会将数据创建在主内存,然后利用 CPU 来计算.在 MXN ...
- 【Linux】防火墙与CentOS中的iptables
[iptables] 参考好文:http://www.zsythink.net/archives/1199.这个博客的作者写了深入浅出的iptables介绍,基本上我就是做个他的读书笔记. ■ 基本介 ...
- Oracle分析函数-排序排列(rank、dense_rank、row_number、ntile)
(1)rank函数返回一个唯一的值,除非遇到相同的数据时,此时所有相同数据的排名是一样的,同时会在最后一条相同记录和下一条不同记录的排名之间空出排名. (2)dense_rank函数返回一个唯一的值, ...
- Navi.Soft31.微信WinForm框架(含下载地址)
1.概述 1.1应用场景 微信的出现,改变了我们日常生活.而微信公众平台的出现,使我们每个人都可能成为一个品牌,微商的普及.微店越来越多.越来越多的人,借助微信公众平台,实现了自己的梦想 在此背景环境 ...
- 【转帖】流程与IT管理部——IT支撑业务变革的必然趋势
流程与IT管理部——IT支撑业务变革的必然趋势 1前言 伴随着中国企业的信息化进程, IT部门.IT专职人员已经在大部分企业获得了一席之地,电脑.网络.软件的维护都离不开这个部门:不过“一席之地”并不 ...
- Java如何在指定端口创建套接字?
在Java编程中,如何在指定端口创建套接字并连接到指定服务器的端口? 下面的例子演示了Socket类的Socket构造函数,并且使用getLocalPort(),getLocalAddress(),g ...