- 浏览: 480880 次
- 性别:
- 来自: 湖南
文章分类
- 全部博客 (201)
- j2ee (43)
- oracle (9)
- mysql (7)
- db2 (1)
- j2se (3)
- spring (1)
- hibernate (3)
- struts (0)
- Berkeley DB (0)
- linux (60)
- Apache2+PHP+MYSQL (2)
- solr (15)
- svn (1)
- IntelliJ Idea (1)
- eclipse,myeclipse (4)
- ant (2)
- vim (8)
- IT生活 (4)
- 测试 (6)
- lucene (4)
- shell (1)
- nutch (18)
- thread (1)
- hadoop (5)
- mapreduce (0)
- Python (4)
- 硬件 (1)
- database (1)
- maven (1)
- 正则表达 (0)
- 互联网 (1)
最新评论
-
youngcoder:
good job
HTTP协议头部与Keep-Alive模式详解 -
javazdq:
受教了 解释的不错。
lucene创建索引高级特性和索引创建参数优化 -
josico:
有几个问题想问下楼主1. LinkedBlockingQueu ...
生产者-消费者-BlockingQueue -
annybz:
有没有关于 BlockingQueue和ConcurrentL ...
生产者-消费者-BlockingQueue -
uniquejava:
多谢,记录的很真实。
DB2 学习记录
一、认识问题:
首先我们通过下面这个
测试程序
来认识这个问题:
运行的环境
(有必要说明一下,不同环境会有不同的结果):32位 Windows XP,Sun JDK 1.6.0_18, eclipse 3.4,
测试程序:
01
|
import
java.util.concurrent.CountDownLatch;
|
02
|
03
|
public
class
TestNativeOutOfMemoryError {
|
04
|
05
|
public
static
void
main(String[] args) {
|
06
|
07
|
for
(
int
i =
0
;; i++) {
|
08
|
System.out.println(
"i = "
+ i);
|
09
|
new
Thread(
new
HoldThread()).start();
|
10
|
}
|
11
|
}
|
12
|
13
|
}
|
14
|
15
|
class
HoldThread
extends
Thread {
|
16
|
CountDownLatch cdl =
new
CountDownLatch(
1
);
|
17
|
18
|
public
HoldThread() {
|
19
|
this
.setDaemon(
true
);
|
20
|
}
|
21
|
22
|
public
void
run() {
|
23
|
try
{
|
24
|
cdl.await();
|
25
|
}
catch
(InterruptedException e) {
|
26
|
}
|
27
|
}
|
28
|
}
|
不指定任何JVM参数,eclipse中直接运行输出,看到了这位朋友了吧:
i = 5602
Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Thread.java:597)
at TestNativeOutOfMemoryError.main(TestNativeOutOfMemoryError.java:20)
二、分析问题:
这个异常问题本质原因是我们创建了太多的线程,而能创建的线程数是有限制的,导致了异常的发生。能创建的线程数的具体计算公式如下:
(MaxProcessMemory – JVMMemory – ReservedOsMemory) / (ThreadStackSize) = Number of threads
MaxProcessMemory 指的是一个进程的最大内存
JVMMemory JVM内存
ReservedOsMemory 保留的操作系统内存
ThreadStackSize 线程栈的大小
在java语言里, 当你创建一个线程的时候,虚拟机会在JVM内存创建一个Thread对象同时创建一个操作系统线程,而这个系统线程的内存用的不是JVMMemory,而 是系统中剩下的内存(MaxProcessMemory – JVMMemory – ReservedOsMemory)。
结合上面例子我们来对公式说明一下:
MaxProcessMemory 在32位的 windows下是 2G
JVMMemory eclipse默认启动的程序内存是64M
ReservedOsMemory 一般是130M左右
ThreadStackSize 32位 JDK 1.6默认的stacksize 325K左右
公式如下:
(2*1024*1024-64*1024-130*1024)/325 = 5841
公式计算所得5841,和实践5602基本一致(有偏差是因为ReservedOsMemory不能很精确)
由公式得出结论:你给JVM内存越多,那么你能创建的线程越少,越容易发生java.lang.OutOfMemoryError: unable to create new native thread。
咦,有点背我们的常理,恩,让我们来验证一下,依旧使用上面的测试程序,加上下面的JVM参数,测试结果如下:
ThreadStackSize JVMMemory 能创建的线程数
默认的325K -Xms1024m -Xmx1024m i = 2655
默认的325K -Xms1224m -Xmx1224m i = 2072
默认的325K -Xms1324m -Xmx1324m i = 1753
默认的325K -Xms1424m -Xmx1424m i = 1435
-Xss1024k -Xms1424m -Xmx1424m i = 452
完全和公式一致。
三、解决问题:
1, 如果程序中有bug,导致创建大量不需要的线程或者线程没有及时回收,那么必须解决这个bug,修改参数是不能解决问题的。
2, 如果程序确实需要大量的线程,现有的设置不能达到要求,那么可以通过修改MaxProcessMemory,JVMMemory,ThreadStackSize这三个因素,来增加能创建的线程数:
a, MaxProcessMemory 使用64位操作系统
b, JVMMemory 减少JVMMemory的分配
c, ThreadStackSize 减小单个线程的栈大小
//—————————————————————————–华丽的分割线——————————————————————————————//
星期一早上到了公司,据称产品环境抛出了最可爱的异常 —OutOfMemory, 它是这样来描述他自己的:
java.lang.OutOfMemoryError: unable to create new native thread
而且这位仁兄竟然还堂而皇之地同时出现在了 3 个 application 里面,所有应用全部遭殃。
那可爱的 OOM 是如何产生的呢?直接原因是创建的线程太多了,根本原因是某个地方的内存限制了。
搜罗了一下在网上找到了一个计算公式:
(MaxProcessMemory – JVMMemory – ReservedOsMemory) / (ThreadStackSize) = Number of threads
MaxProcessMemory :进程最大的寻址空间,但我想这个值应该也不会超过虚拟内存和物理内存的总和吧。关于不同系统的进程可寻址的最大空间,可参考下面表格:
Maximum Address Space Per Process |
|
Operating System |
Maximum Address Space Per Process |
Redhat Linux 32 bit |
2 GB |
Redhat Linux 64 bit |
3 GB |
Windows 98/2000/NT/Me/XP |
2 GB |
Solaris x86 (32 bit) |
4 GB |
Solaris 32 bit |
4 GB |
Solaris 64 bit |
Terabytes |
JVMMemory: Heap + PermGen
ReservedOSMemory : Native heap , JNI
便可推导出单个 JVM Instance可支持的最大线程数的估计值:
(MaxProcessMemory<固定值 > – Xms<初始化值,最小值 > – XX:PermSize<初始化值,最小值 > – 100m<估算值 >) / Xss = Number of threads<最大值 >
在本地 (32bit windows)试了试,可达的线程的最大值差不多就是这个数,它不受物理内存的限制,会利用虚拟内存,从任务管理器看到 memory已经是 5500 m左右了(开了两个 jvm),我机器的物理内存是 2g,也不知道这个准不准,后来还抛出了“ unable to create new native thread ”的兄弟“ Exception in thread "CompilerThread0" java.lang.OutOfMemoryError: requested 471336 bytes for Chunk::new. Out of swap space?“。
本地测完了后,就该轮到 dev环境了, linux2.6, 64bit,双核, 8G(虚拟机),总的物理内存是 16g。在上面整了一下,创建到了 15000多个线程的时候挂掉了。此时其他 application也不能创建新的线程,而且 db也报错了,操作系统不能 fork新的线程了。这应该是操作系统的哪里限制了新线程的创建,
· max thread, linux2.6似乎是 32000
· 最大可用内存:物理内存 +虚拟内存
· 配置,在 linux可以限制可用资源的大小, show一下这些参数
core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited file size (blocks, -f) unlimited pending signals (-i) 1024 max locked memory (kbytes, -l) 32 max memory size (kbytes, -m) unlimited open files (-n) 65536 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 stack size (kbytes, -s) 10240 cpu time (seconds, -t) unlimited max user processes (-u) 16384 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited |
为了进一步确定在 linux上一个 jvm因为达到了最大寻址空间 OOM了,不会影响其他 jvm,我在 Linux做了进一步测试,一开始用 Sun文档中说的最大寻址空间 3G试了一下,发现根本不对,达到了 3G后还是非常 high地在创建新的线程。于是出动超级无敌变态的 JVM初始化配置。
oracle 27408 27017 12 13:45 ? 00:00:07 /home/oracle/ias1013/FWAPP/FWDev/jdk/bin/java -server -Xmx4096m -Xms4096m -XX:+HeapDumpOnOutOfMemoryError -XX:PermSize=4096m -XX:MaxPermSize=4096m -XX:HeapDumpPath=/home/oracle/ias1013/FWAPP/FWDev/j2ee/OC4J_OOMTest/workEnv/log -Xss100m |
结果在 create 3379个线程后,“ unable to create new native thread ”出现了,这时其他 jvm都是可以 create新线程的。如果按照上面公式计算, linux 64bit, 2.6kernel,它的最大寻址空间肯定超过了 300g,当然应该还没有达到可用内存的限制,因为其他 JVM还能 create新线程。
我还怀疑是不是 oracle application server上的某个配置参数限制了总的线程数,影响了所有 application,但我们的产品环境一个 application就是一个单独的application server。
现在基本上可以确定是操作系统哪里设置错了,我想 System team的帅哥们应该把产品环境的某个参数配置错了,系统本身的影响肯定不会有了,因为产品环境上我们只 create了 800左右个线程,就OOM了,那应该就是配置的问题了,怀疑的参数有下面四个
max user processes (-u) 2048
virtual memory (kbytes, -v) unlimited
max memory size (kbytes, -m) unlimited
stack size (kbytes, -s) 10240
最后发现只有 max user processes 和 virtual memory对总的线程数有影响,我把 max user processes降到 2048后,发现此时只能创建 2000左右个线程了 (Xms64m, Xss1m),进一步地把 virtual memory下调到 2048000K发现能创建的就更少了 1679( Xms64m, Xss1m),而它只会对当前shell起作用,而多个application server应该是不同的shell,所以他是打酱油的 。另外两个参数好像就是来做做俯卧撑的,操作系统 stack size是不应该会有什么影响,我们把它上调到 102400,还是可以创建 2000左右的线程数( max user processes), 因为 java有自己的线程模型,它的栈的大小是用 Xss来控制的。 Max memory size不知道是啥东东,照理说如果是最大内存应该不会只在旁边做俯卧撑,那这个参数到底是春哥还是曾哥,查了一下 man ulimit,有下面解释
-a All current limits are reported
-c The maximum size of core files created
-d The maximum size of a process data segment
-f The maximum size of files created by the shell
-l The maximum size that may be locked into memory
-m The maximum resident set size (has no effect on Linux)
-n The maximum number of open file descriptors (most systems do not allow this value to be set)
-p The pipe size in 512-byte blocks (this may not be set)
-s The maximum stack size
-t The maximum amount of cpu time in seconds
-u The maximum number of processes available to a single user
-v The maximum amount of virtual memory available to the shell
“ Has no effect on Linux”就足以证明它确实只是来做做俯卧撑的。最后查出只有“ max user processes”会对所有 application能创建总的线程数有限制。
发表评论
-
Maven使用deploy命令部署构建
2012-07-18 17:13 2465个人技术博客:http:/ ... -
Java 对象序列化您不知道的 5 件事
2012-07-04 14:56 1447个人技术博客:http://demi-panda.com ... -
Solr 获取分词
2012-05-07 18:32 3578个人博客:http://demi-panda.com ... -
地图经纬度距离计算
2012-03-30 15:43 2408public static final doubl ... -
ThreadLocal类
2012-03-01 18:38 937个人技术博客:http://demi-panda.com ... -
Spring MVC中默认的ResponseBody为String的乱码问题
2011-12-22 16:54 1420个人技术博客:http://demi-panda.com ... -
ASCII和中文互转
2011-07-29 13:34 3820个人技术博客:http://demi-panda.com ... -
JVM 参数详解
2011-07-06 14:23 6486个人技术博客:http://demi-panda.com ... -
URL encode
2011-06-22 15:00 3116个人技术博客:http://demi-panda.co ... -
笔记之三-robots
2011-06-16 16:13 1142一、robots robots主要作用是屏蔽一些不愿意让 ... -
HTTP协议头部与Keep-Alive模式详解
2011-06-16 15:55 17343个人技术博客:http://demi-panda.com ... -
java.net.SocketException: Too many open files解决方法
2011-03-24 15:34 1207Get current limit: ulimit - ... -
利用HAProxy实现负载均衡
2011-02-14 11:04 2488HAProxy的安装和部署 Posted o ... -
负载均衡工具haproxy安装,配置,使用
2011-02-12 11:28 3919一,什么是haproxy HAProxy提供高可 ... -
Java编程思想第四版 完整中文版下载
2011-01-09 21:11 4167个人技术博客:http://demi-panda.com ... -
Java 理论与实践: 正确使用 Volatile 变量
2011-01-06 23:45 489Java 语言中的 volatile ... -
Java常用正则表达式
2010-12-08 20:41 947"^\d+$" //非负整数(正整数 + ... -
JConsole远程连接
2010-12-02 13:58 1028JConsole很好用,可以解决很多疑难杂症。但远程连接需要设 ... -
JVM配置参数中文说明
2010-12-02 13:04 1227JVM配置参数中文说明: -------- ... -
Java 代理模式与动态代理类
2010-11-21 16:51 3558代理模式与Java 动态代理类 ...
相关推荐
3. **无法创建新的本地线程 (Unable to create new native thread)**: - 每个Java应用在操作系统上都表现为一个或多个线程。当JVM尝试创建新线程但操作系统报告无可用资源时,会抛出此错误。 - 这可能是由于系统...
【Java虚拟机内存溢出分析】:当遇到`java.lang.OutOfMemoryError: unable to create new native thread`错误时,这通常表示系统无法为新的Java线程分配足够的内存,即操作系统层面的资源耗尽,而非Java堆内存不足。...
5. 无法创建新的原生线程(Unable to create new native thread) 当JVM尝试创建新的线程时,如果无法获取足够的原生内存来分配新线程的栈空间,就会抛出该错误。通常发生在系统限制了线程数量或是原生内存不足时。 ...
- **错误日志**:`java.lang.OutOfMemoryError: unable to create new native thread` 和 `java.lang.OutOfMemoryError: request bytes for ... Out of swap space?` - **原因**:可能由于Java堆设置过大导致...
【情况五】:`java.lang.OutOfMemoryError: unable to create new native thread` 这表明系统无法创建新的原生线程,可能是由于线程栈空间不足或者系统资源限制。解决方法包括减少单个线程栈大小(使用`-Xss`参数)...
OutOfMemoryError的8种经典案例,Java heap space、GC overhead limit exceeded、Permgen space、Metaspace、Unable to create new native thread、Out of swap space?、Requested array size exceeds VM limit、...
在使用Dubbo进行分布式服务调用的过程中,可能会遇到“无法创建新线程”的异常情况,具体表现为`java.lang.OutOfMemoryError: unable to create new native thread`。此类异常通常出现在系统资源紧张的情况下,特别...
5. Unable to Create New Native Thread 错误 * 原因分析:JVM 向 OS 请求创建 native 线程失败 * 解决方案:增加 JVM 的堆内存空间、调整 JVM 的线程池大小、优化线程的使用 6. Requested Array Size Exceeds VM ...
系统会提示出错,前台错误为:HTTP Status 500-Dispatch[EAITool] to method listCurTree retrun an exception,后台错误为:java.lang.OutOfMemoryError: unable to create new native thread。 解决方法: 为了...
- **java.lang.OutOfMemoryError: unable to create new native thread**:无法为线程分配内存。 - **java.lang.OutOfMemoryError: request bytes for**:地址空间不足。 解决内存溢出问题,首先需要查看监控工具...
java.lang.OutOfMemoryError: unable to create new native thread ``` 或是在启动服务时收到: ``` /etc/profile: fork: retry: Resource temporarily unavailable ``` 这些错误通常表明系统中的线程资源已经...
首先,我们遇到的第一个问题是“意外的异常”和“java.lang.OutOfMemoryError: unable to create new native thread”。这通常发生在尝试上传大型应用war包至WebLogic管理服务器时。由于应用较大,系统内存不足,...
3. **OutOfMemoryError: unable to create new native thread** - 当系统无法为新的线程分配内存时,会出现此类错误。这通常是由于操作系统级别的限制导致的。 #### 二、内存溢出的原因分析与解决策略 ##### 1. ...
当应用程序尝试创建超过这个限制的线程时,可能会抛出`java.lang.OutOfMemoryError: unable to create new native thread`异常。这个限制是防止恶意或意外的进程消耗过多系统资源,导致所谓的“fork炸弹”。 实战...
- **无法创建新原生线程**(`java.lang.OutOfMemoryError: unable to create new native thread`):当操作系统没有足够的资源来创建新线程时发生,可以通过调整`-Xss`参数来减少分配给单个线程的栈空间大小。...
Java 中 Executor, ExecutorService 和 Executors ...通过理解它们之间的区别,我们可以更好地使用线程池来提高应用的响应时间,避免“java.lang.OutOfMemoryError: unable to create new native thread”之类的错误。