JVM的分配

 

从实际应用的角度来说。-Xmx大了不是很好,垃圾回收需要更多的时间,但是thread问题就很大,配给JVM的内存数越大,tomcat所能开的thread数就越小,最后出现ava.lang.OutOfMemoryError: unable to create new native thread。根据我在windows下编程经验,windows起的线程栈的大小写在可执行文件头,默认是1M。对于java来说,如果采用默认xss设置,jdk1.4每线程256k, jdk1.5每线程1M。如果设置没有超过1M, 又不是默认设置,那么jdk就会为每个线程分配1M。
对于windows来说,32位使用最大内存为2G,如果你给jvm分1.5G,剩余大约500M,供OS使用,其中windows的dll占了一部分,但是你在JVM创建线程的时候,创建的是OS的线程,他要从剩余的空间中分配内存。如果没有可用内存,出现上述错误。
参看hotspot/src/share/vm/runtime/os.c
 { MutexLocker mu(Threads_lock);
      JavaThread* signal_thread = new JavaThread(&signal_thread_entry);
                                                                                                                             
      // At this point it may be possible that no osthread was created for the
      // JavaThread due to lack of memory. We would have to throw an exception
      // in that case. However, since this must work and we do not allow
      // exceptions anyway, check and abort if this fails.
      if (signal_thread == NULL || signal_thread->osthread() == NULL) {
        vm_exit_during_initialization("java.lang.OutOfMemoryError",
                                      "unable to create new native thread");
      }
公式如下
(MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads
解决的办法就是减少-Xmx的数量,减少xss的值,或者开启3GB模式。

最主要的还是程序员的编程,对于网络编程,在nio出来之前,每一个线程只能处理一个socket请求,也就是说一个socket连接需要一个线程,这样使服务器的并发收到了限制,压力不能过大,因为服务器开启thread有限,这造成了tomcat的性能远不如apache。nio出来之后,在一个线程内处理几个连接成为了可能,几乎所有的java的开源web服务器,tomcat6,jetty都用nio重写了网络连接部分,resin使用自己的实现,不开源的apusic也用了nio。

你可能感兴趣的:(jvm,thread,signal,windows,initialization,tomcat)