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, uml
下面是Java Collections Framework的类图,没有将current包底下的内容加入。 Read the rest of this entry »
07年的时候就用过JNI这东西了,那时候是为了给项目的J2EE应用写一个授权功能,通过调用vc写的读取硬件id的dll使得cdkey能够跟机器一一对应起来,从而做到控制一个cdkey只能装到一台机器上上。那会儿用的dll是别人写的,java中调用dll也是用的小日本儿写的一个叫jcom的组件,这次决定自己做一遍整个流程.
- 编写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定义的路径下啊。
- 用javac编译该文件,不用讲。
- 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 - 创建一个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函数,才解决了中文乱码的问题。 - 编译完会成成一个dll文件,拷贝到java.library.path下,我是拷贝到了c:\windows下。
- 编写一个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,哈狗帮!"); } } - ok,这下就完成了从java程序中调用win32 API弹出windows原生的窗口了 。
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”就可以得到正确的结果了。
基本概念:
PermGen space:全称是Permanent Generation space。就是说是永久保存的区域,用于存放Class和Meta信息,Class在被Load的时候被放入该区域
Heap space:存放Instance。 Read the rest of this entry »
Java平台提供了一个全新的集合框架。“集合框架”主要由一组用来操作对象的接口组成。不同接口描述一组不同数据类型。

Java 2集合框架图 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: java, javac
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 »

