显示标签为“跟我学Java26日通”的博文。显示所有博文
显示标签为“跟我学Java26日通”的博文。显示所有博文

2012年3月12日星期一

java.lang.OutOfMemoryError: PermGen space

最近把网站又一次升级..加入了spring..又添加了一些功能. 

发布运行很成功. 
但好景不长啊.过不了几天就发现服务器宕机了... 

通过LOG4J的记录也发现不了什么..显示一切正常.甚是奇怪啊. 

后来通过几次重启Tomcat.发现了更严重的问题,重启后,自己点击几个链接都会出现了宕机现象. 

很是不解... 

不能天天让客服MM重启服务器啊.她烦我更烦啊. 
只能让MM把tomcat的运行日志发给我看看了... 

看看日志: 
引用

2008-10-29 18:00:43 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet jsp threw exception
java.lang.OutOfMemoryError: PermGen space

SEVERE: An exception or error occurred in the container during the request processing
java.lang.OutOfMemoryError: PermGen space
2008-10-29 18:36:21 org.apache.tomcat.util.threads.ThreadPool$ControlRunnable run
SEVERE: Caught exception (java.lang.OutOfMemoryError: PermGen space) executing org.apache.jk.common.ChannelSocket$SocketConnection@4af41d, terminating thread 


完全的蒙了..怎么会有这种错误..内存溢出啊. 

在自己的机子上只有512的内存都没有溢出,而且压力测试得蛮好. 

怎么到了服务器上这种问题都出现了. 

GOOGLE了一把: 
解决问题的方法还是有的: 
引用

一、java.lang.OutOfMemoryError: PermGen space

PermGen space的全称是Permanent Generation space,是指内存的永久保存区域,
这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中,
它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对
PermGen space进行清理,所以如果你的应用中有很多CLASS的话,就很可能出现PermGen space错误,
这种错误常见在web服务器对JSP进行pre compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大小
超过了jvm默认的大小(4M)那么就会产生此错误信息了。
解决方法: 手动设置MaxPermSize大小

修改TOMCAT_HOME/bin/catalina.sh
在“echo "Using CATALINA_BASE:   $CATALINA_BASE"”上面加入以下行:
JAVA_OPTS="-server -XX:PermSize=64M -XX:MaxPermSize=128M"
建议:将相同的第三方jar文件移置到tomcat/shared/lib目录下,这样可以达到减少jar 文档重复占用内存的目的。

二、java.lang.OutOfMemoryError: Java heap space
Heap size 设置
JVM堆的设置是指java程序运行过程中JVM可以调配使用的内存空间的设置.JVM在启动的时候会自动设置Heap size的值,
其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。可以利用JVM提供的-Xmn -Xms -Xmx等选项可
进行设置。Heap size 的大小是Young Generation 和Tenured Generaion 之和。
提示:在JVM中如果98%的时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息。
提示:Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值。
解决方法:手动设置Heap size
修改TOMCAT_HOME/bin/catalina.sh
在“echo "Using CATALINA_BASE:   $CATALINA_BASE"”上面加入以下行:
JAVA_OPTS="-server -Xms800m -Xmx800m   -XX:MaxNewSize=256m"

三、实例,以下给出1G内存环境下java jvm 的参数设置参考:

http://blog.csdn.net/oiote/archive/2008/07/25/2707877.aspx

JAVA_OPTS="-server -Xms800m -Xmx800m -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=128m -Djava.awt.headless=true "


如果用的是安装版的tomcat 
http://www.cnblogs.com/midnight/archive/2008/07/24/1204862.html 
引用

参数加的位置:  
  tomcat5w.exe就是启动后显示在任务栏上的:  
  java---->java  options里  
  -Dcatalina.home=D:\JavaTools\Tomcat   5.5  
  -Djava.endorsed.dirs=D:\JavaTools\Tomcat   5.5\common\endorsed  
  -Djava.io.tmpdir=D:\JavaTools\Tomcat   5.5\temp  
  -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManage  
  原来应该有这样的  
  只要再加上一行:  
-XX:MaxPermSize=256MB 

Hibernate 复合主键(composite-id)查询


Hibernate逆向生成无主键的数据表时产生的hbm如:
  

 <class name="class_name" table="table_name" schema="schema_name">
        
<composite-id name="id" class="class_name">
            
<key-property name="property_name" type="type_name">
                
<column name="column_name" length="20" />
            
</key-property>
            
        
</composite-id>
</class>   Hibernate不允许无PrimaryKey的ORM,因此会独立生成此对象为ORM的PrimaryKey

  当需要查询此表,如果此对象中有任意一个字段为NULL,则整条记录都为NULL
  因为Hibenrate约束主键不能为空。
  解决办法:可将composite-id标签里可能会为空的字段提取到composite-id外,
  将数据表所对应的POJO添加字段,字段为提取到composite-id标签外的字段属性
  HQL查询时直接用对应的类索引属性查询,无需经过第三方生成类

2012年3月9日星期五

2012年1月19日星期四

Mixed Java and C++ Programming

步骤
  1. 编写带有native声明的方法的java类
  2. 使用javac命令编译所编写的java类
  3. 使用javah -jni java类名生成扩展名为h的头文件
  4. 使用C/C++实现本地方法
  5. 将C/C++编写的文件生成动态连接库
例子
1) 编写java程序:
[javanative]$ cat HelloWorld.java================
public class HelloWorld {
    //declare interface to C function
    public native void displayHelloWorld();
    static {
        //load shared libs built from C code
        System.loadLibrary("hello");
    }

    public static void main(String[] args) {
        //call C function
        System.out.println("Hello World from Java");
        new HelloWorld().displayHelloWorld();
    }
}
声明native方法:如果你想将一个方法做为一个本地方法的话,那么你就必须声明改方法为native的,并且不能实现。其中方法的参数和返回值在后面讲述。

Load动态库:System.loadLibrary("hello");加载动态库(我们可以这样理解:我们的方法 displayHelloWorld()没有实现,但是我们在下面就直接使用了,所以必须在使用之前对它进行初始化)这里一般是以static块进行加载 的。同时需要注意的是System.loadLibrary();的参数“hello”是动态库的名字(libhello.so or hello.dll)

2) 编译没有什么好说的了
javac HelloWorld.java

3) 生成扩展名为h的头文件
javah -jni HelloWorld


[javanative]$ cat HelloWorld.h=================
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */

#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloWorld
 * Method:    displayHelloWorld
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif


4) 编写C++本地方法
[javanative]$ cat HelloWorld.cpp==================
#include "HelloWorld.h"
#include <iostream>
using namespace std;

JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
  (JNIEnv *, jobject)
{

    cout<<"Hello World from C++"<<endl;
    return;
}


5) 生成动态库
  g++ -shared -fPIC -o libhello.so -I/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/include/ -I/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/include/linux HelloWorld.cpp

6) 运行程序
java -Djava.library.path=/path/to/current/dir/javanative HelloWorld
Hello World from Java
Hello World from C++


Java HotSpot VM 簡介

http://blog.csdn.net/xiaojianpitt/article/details/4493210


結語

Java HotSpot VM 在程式方面做了更強的最佳化處理,另外,在 garbage collection 還有 thread 同步方面也做了相當大的改進。除此之外,Java HotSpot VM 對於 client 和 server 端的應用程式,分別提供了不同的執行環境,使的應用程式在執行的時候,可以獲得最好的效果。若是大家對於 Java HotSpot VM 有興趣的話,可以到http://java.sun.com/products/hotspot/index.html 這邊獲得更多的相關資料。


看看你下面的这两个文件,是不是尺寸差别很大?
%JAVA_HOME%/jre/bin/client/jvm.dll
%JAVA_HOME%/jre/bin/server/jvm.dll
Jvm 动态库有 client 和 server 两个版本,分别针对桌面应用和服务器应用做了相应的优化, client 版本加 载速度较快, server 版本加载速度较慢但运行起来较快。
让 Tomcat 使用 Server 版本的 jvm 吧 在开始菜单 tomcat5 ->tomcat config 的 java 属性中 有一项 jvm 路径 指向 server 目录下的 jvm 就行了。
启动速度对比一下,在我的 C4.17 512M 的机器上 client 版本一般在 8s-16s 内启动完成 server 版本 在 21s-26s 左右启动完成。


更改默认 java.exe 调用的 jvm.dll, 这个由 jvm.cfg 决定。
编辑 %JAVA_HOME%/jre/lib/i386/jvm.cfg

里面第一行写的是 -client 默认就是 client 版本 ,把第二行的 -server KNOWN 放到第一行, 如下面所示
-server KNOWN
-client KNOWN
-hotspot ALIASED_TO -client
-classic WARN
-native ERROR
-green ERROR
改完保存,然后看看默认版本:
C:/java -version
java version "1.4.2_07"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_07-b05)
Java HotSpot(TM) Server VM (build 1.4.2_07-b05, mixed mode)
看到没有 Server VM 字样?是不是很酷啊!,小心机器不够快,启动等得你疯掉 :)

AFAIK, the JRE usually doesn't ship with a server VM (only the client VM). If you really need the server VM, you have to use the JDK installation.

2012年1月14日星期六

RHEL5整合Apache+Tomcat,支持jsp与php - guolr - ITeye技术网站

RHEL5整合Apache+Tomcat,支持jsp与php - guolr - ITeye技术网站

  install tomcat
             yum install tomcat5 ( not yum install tomcat5-...-version )
             yum search webapp (and install manger and admin webapp)

   httpd:   /etc/httpd/conf/httpd.conf
               ProxyPass /mej http://ghost:8080/mej
               ProxyPass /bq http://ghost:8080/bq
               ProxyPass /mydemo http://ghost:8080/mydemo
               (must config for all java ee project)

   tomcat:  /etc/tomcat5/tomcat5.conf
               User tomcat
               Group tomcat
               CATALINA_HOME="/usr/share/tomcat5"
               DocumentRoot $CATALINA_HOME/webapps/ROOT/index.html
            /etc/tomcat5/server.xml
                <Context path="/me" docBase="/u/me/web"/>
                <Context path="/mej" docBase="/u/me/webj"/>
                <Context path="/bq" docBase="/u/me/webj/bq/WebContent"/>
                (must config all projects except those under tomcat webapps)
            /etc/tomcat5/tomcat-users.xml
                <role rolename="admin"/>
                <role rolename="manager"/>
                <user username="admin" password="admin" roles="admin,manager,tomcat"/>

   my httpd or tomcat5 http://ghost/mydemo     http://ghost:8080/mydemo  document: tomcat_webapps/mydemo
   my httpd or tomcat5 http://ghost/bq         http://ghost:8080/bq      document: ~/webj/bq/WebContent

2012年1月1日星期日

第11天第4节: 生产者-消费者

public class Phone {
    String name = "Iphone";
    boolean empty = true;

    public synchronized void produce(String name) {
        if (!empty) {
            try {
                super.wait(); // already have, wait
            } catch (Exception e) {
            }
        }

        this.name = name; // producing phone
        empty = false;

        super.notify();
    }

    public synchronized String comsume() {
        if (empty) {
            try {
                super.wait(); // have to wait
            } catch (Exception e) {
            }
        }

        empty = false;

        super.notify();
        return this.name;
    }
}

class producer{....}
class comsummer{....}
class tester{...}

第11天第3节: 线程的操作方法

见上一节

第11天第2节: 多线程两种实现方式

==实现线程的两种方式
1. extends Thread类

class Mythread extends Thread {
    public String name = null;

    public Mythread(String name){
        this.name = name;
    }
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(name + i);
        }
    }

}

public class Dthread extends Thread {
    public static void main(String[] args) {
        Mythread m1 = new Mythread("A ");
        Mythread m2 = new Mythread("B ");
        Mythread m3 = new Mythread("C ");
       
        m1.start();
        m2.start();
        m3.start();

    }

}

2. implement Runnable 接口: Can use shared variables: 代理设计模式

class Mythread2 implements Runnable {
    int ticket = 5;

    public void run() {
        for (int i = 0; i < 5; i++) {
            try {
                Thread.currentThread().sleep(500);
                if (ticket > 0) {
                    System.out.println(Thread.currentThread().getName() + ticket--);
                }
            } catch (Exception e) {
                System.out.println(Thread.currentThread().getName() + "被中断了");
                return;
            }
        }
    }
}

public class Drunnable extends Thread {
    public static void main(String[] args) {
        Mythread2 mt = new Mythread2();

        Thread m1 = new Thread(mt, "AA ");
        Thread m2 = new Thread(mt, "BB ");
        Thread m3 = new Thread(mt, "CC ");

        m1.start();
        m2.start();
        m3.start();
        try {
            Thread.currentThread().sleep(1000); // main thread sleep
        } catch (Exception e) {
        }
        System.out.println("主线程对各线程发出中断请求");
        m1.interrupt();
        m2.interrupt();
        m3.interrupt();

    }

}

----java output----
BB 5
CC 3
AA 4
主线程对各线程发出中断请求
BB 被中断了
AA 被中断了
CC 2
CC 被中断了

===线程的同步