JVM Class Loader详解

Posted by Wayne Wan in Java Foundation on 03-07-2010

Tags: ,

classloader.png

     Read the rest of this entry »

JVM内存模型以及垃圾收集策略解析

Posted by Wayne Wan in Java Foundation on 23-02-2010

 

 一 JVM内存模型

1.1 Java栈

Java栈是与每一个线程关联的,JVM在创建每一个线程的时候,会分配一定的栈空间给线程。它主要用来存储线程执行过程中的局部变量,方法的返回值,以及方法调用上下文。栈空间随着线程的终止而释放。

StackOverflowError:如果在线程执行的过程中,栈空间不够用,那么JVM就会抛出此异常,这种情况一般是死递归造成的。 Read the rest of this entry »

Java Collections Framework Diagram

Posted by Wayne Wan in Java Foundation on 21-01-2010

Tags: ,

下面是Java Collections Framework的类图,没有将current包底下的内容加入。 Read the rest of this entry »

Java JNI学习

Posted by Wayne Wan in Java Foundation, c/c++ on 29-12-2009

Tags:

    07年的时候就用过JNI这东西了,那时候是为了给项目的J2EE应用写一个授权功能,通过调用vc写的读取硬件id的dll使得cdkey能够跟机器一一对应起来,从而做到控制一个cdkey只能装到一台机器上上。那会儿用的dll是别人写的,java中调用dll也是用的小日本儿写的一个叫jcom的组件,这次决定自己做一遍整个流程.

  1. 编写java文件
    /**
     * Copyright (C), 2009-2010
     * File Name: jni.WinMessage.java
     * Encoding UTF-8
     * Version: 1.0
     * Date: Dec 29, 2009
     * History:
     */
    package jni;
    
    /**
     *
     * @author (bestirwiny@gmail.com)
     * @version Revision: 1.00 2:12:24 PM
     */
    public class WinMessage
    {
    	static{
    		System.loadLibrary("WinMsgDll");
    	}
    	public native void showMsgBox(String msg);
    }
    

    loadLibrary用于load一个dll,该dll应该在java.library.path定义的路径下啊。

  2. 用javac编译该文件,不用讲。
  3. javah -jni WinMessage,会生成一个jni_WinMessage.h的头文件,下面要做的工作就是dll的编写了。
    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include "jni.h"
    /* Header for class jni_WinMessage */
    
    #ifndef _Included_jni_WinMessage
    #define _Included_jni_WinMessage
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     jni_WinMessage
     * Method:    showMsgBox
     * Signature: (Ljava/lang/String;)V
     */
    JNIEXPORT void JNICALL Java_jni_WinMessage_showMsgBox
      (JNIEnv *, jobject, jstring);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    
  4. 创建一个win32动态连接库的工程,将$JAVAHOME/include,$JAVA_HOME/include/win32目录加入到工程需要引用的头文件路径中。
    #include "tchar.h"
    #include "stdlib.h"
    #include "stdio.h"
    #include "AtlBase.h"
    #include "AtlConv.h"
    #include "windows.h"
    #include "jni_WinMessage.h"
    
    /*
     * Class:
     * Method:    showMsgBox
     * Signature: (Ljava/lang/String;)V
     */
    JNIEXPORT void JNICALL Java_jni_WinMessage_showMsgBox
      (JNIEnv * env, jobject jobj, jstring str){
    	const char * msg;
    	msg = env->GetStringUTFChars(str,0);
    
    	WCHAR* strA;
        int i= MultiByteToWideChar ( CP_UTF8 , 0 ,msg ,-1 ,NULL,0);
    	strA = new WCHAR[i];
    	MultiByteToWideChar ( CP_UTF8 , 0 ,( char * ) msg, -1, strA , i );
    
    	USES_CONVERSION;
    	MessageBox(NULL,strA,_T("Java invoke "),MB_OK);
    	env->ReleaseStringUTFChars(str,msg);
    }
    

    由于win32变成才开始学,所以这个东西弄了好久才弄好,网上的例子中通过GetStringUTFChars取回的msg直接传到MessageBox中用,可我用的是VS2008,直接用会报错误,大致是说不能将const char *转换为LPCWSTR * ,
    LPCWSTR是long pointer constant wide string的意思,是一种wchar_t类型,char类型占用一个byte,而wchar_t占用两个byte,所以这边就要用一个转换 函数,网上查好久才查到MutiByteToWideChar函数,才解决了中文乱码的问题。

  5. 编译完会成成一个dll文件,拷贝到java.library.path下,我是拷贝到了c:\windows下。
  6. 编写一个java类调用上面的WinMessage
    /**
     * Copyright (C), 2009-2010
     * File Name: jni.TestWinMessage.java
     * Encoding UTF-8
     * Version: 1.0
     * Date: Dec 29, 2009
     * History:
     */
    package jni;
    
    /**
     *
     * @author (bestirwiny@gmail.com)
     * @version Revision: 1.00 4:54:25 PM
     */
    public class TestWinMessage
    {
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args)
    	{
    		WinMessage wm = new WinMessage();
    		wm.showMsgBox("MC Hotdog,哈狗帮!");
    	}
    }
    
  7. ok,这下就完成了从java程序中调用win32 API弹出windows原生的窗口了 。

Java位运算

Posted by Wayne Wan in Java Foundation, Reviews on 09-01-2009

Tags: ,

      Java算是一门很高级的语言了,平时使用一般不会用到位运算这种很低级的特性,但在有些地方有很高的性能或者空间的要求可能会用到,比如说手机平台。今天偶尔看了下,发现一些基础只是很长时间没有搞都忘记了,今天看到相关的东西以至于想了很久才想通。就从今天看到的一段代码来回顾些基础知识,是一段将int转换为byte数组的代码。

———————————————————–
//cout为自己包装的打印方法
  int a = 645765765;
  cout(a);
  cout(Integer.toBinaryString(a));
  byte[] b = new byte[4];
     b[0] = (byte)((a>>24)&0xff);
     cout(Integer.toBinaryString(b[0]&0xff));
     b[1] = (byte)((a>>16)&0xff);
     cout(Integer.toBinaryString(b[1]&0xff));
     b[2] = (byte)((a>>8)&0xff);
     cout(Integer.toBinaryString(b[2]&0xff));
     b[3] = (byte)((a>>0)&0xff);
     cout(Integer.toBinaryString(b[3]&0xff));
    
     int decodeA ;
     decodeA = b[0]&0×000000ff;
     decodeA = (decodeA<<8) + (b[1]&0xff);
     decodeA = (decodeA<<8) + (b[2]&0xff);
     decodeA = (decodeA<<8) + (b[3]&0xff);
     cout(decodeA);
//自己写的另外一种转换方法
     int decodeA2 ;
     decodeA2  = ((b[0]&0xff)<<24);
     decodeA2 += ((b[1]&0xff)<<16);
     decodeA2 += ((b[2]&0xff)<<8);
     decodeA2 += ((b[3]&0xff)<<0);
     cout(decodeA2);
——————————————————————–

      一开始看到的黑体部分。于是写了下面红色的版本,但之前不是现在这个正确版本,之前是这样的。
     int decodeA2 ;
     decodeA2  = b[0]<<24;
     decodeA2 += b[1]<<16);
     decodeA2 += b[2]<<8;
     decodeA2 += b[3]<<0;
     cout(decodeA2);
    结果只要a的值一超过128就会出错,百思不得其解,之后查了有关移位的资料。右移在java中有两种方式,一种是带符号的,一种是不带符号的,带符号的会根据最高位的值来判断用1还是0来补足,若最高位为1则用1来补,若为0则用0来补,无符号的则全部用0补,而对于左移则全部用0补。想了很久这个似乎也没有关系,最后偶然间看到byte的最高位是用来表示正负的,就是说byte的值为-128到127,所以只要在遇到了某一byte的最高位为1的情况下就会出现该值变为了一负值,但其实这个时候它里面存的位信息还是对的,用Integer的int到二进制的一个方法将其打出来便可以发现是一个32位的高位全为1的二进制形式,及是一个负数,于是对它在进行一次“与运算”去掉高位的“1”就可以得到正确的结果了。

JVM参数详解以及配置调优

Posted by Wayne Wan in Java Foundation on 05-01-2009

Tags: ,

基本概念:

PermGen space:全称是Permanent Generation space。就是说是永久保存的区域,用于存放Class和Meta信息,Class在被Load的时候被放入该区域
Heap space:存放Instance。
Read the rest of this entry »

Java timezone设置问题

Posted by Wayne Wan in About Work, Reviews on 01-01-2009

Tags:

    上个月碰到一个问题,有一个客户在装了俺们的系统后出现时间错误问题,查了很长时间也没有查到问题所在。后来上google查了下,在sun的网站上查到有人遇到过类似的一个问题,不过那人描述的好像是jdk1.4中的,解决办法就是下载sun出的一个TZupdater的补丁包,它会修正一些时区的问题,可我们的系统用的都是jdk6,应当是不存在这样的问题的。服务器上的时间是正常的北京时间,查看了服务器上的时区设置也是东八区,操作系统是server 2003,按照我的理解jre在默认的情况下应当是去取操作系统的时区的(当然只是猜测),可以查俺们应用的log发现log4j打印出来的日志时间也是错的,跟我们的应用一样时间出现好几个小时的偏差,后来查了下好像我们的应用内用的是北美时区,最后在resin启动的参数中加了 -Dtimezone=asia/shanghai 使得在resin启动的时候就将运行时环境人工设置到asia/shanghai上来,重启resin,问题就解决了。今天又碰到同样的问题,可不同的是我无论怎样设置时区问题依然存在,有点儿搞不明白了,希望在元旦长假过后能顺利解决这个问题。

Java集合框架详解

Posted by Wayne Wan in Java Foundation on 18-12-2008

Tags: ,

         Java平台提供了一个全新的集合框架。“集合框架”主要由一组用来操作对象的接口组成。不同接口描述一组不同数据类型。 

92084.bmp
Java 2集合框架图  Read the rest of this entry »

寒冬真的要来了吗?

Posted by Wayne Wan in Reviews on 23-11-2008

Tags: , ,

    晚上看完电视打开电脑没事儿,看了几篇时寒冰的博客,感触颇深,也使得本来不乐观的我更悲观了。
    里面讲到当前中国的状况完全就是日本89年经济危机的翻版,于是查了些有关日本89年经济危机的资料。80年代的日本发展迅速,贸易顺差巨大,跟老美之间的贸易摩擦也跟当前的中国一样频频,在老美的压力之下被迫日元升值,在这样的环境下,日本国内为了刺激经济也采取的是及其宽松的货币政策,低的不能再低的利率。 Read the rest of this entry »

Using the javac and java Commands

Posted by Wayne Wan in English Study, Java Foundation on 19-09-2008

Tags: ,

  1.Compiling with javac
    javac [options] [source files]
    Both the [options] and the [source files] are optional parts of the command, and both allow multiple entries.
    eg: javac -help
          javac -classpath com:. -g Foo.java Bar.java Read the rest of this entry »