1.final 变量必须被初始化,之后不可以改变。
2.final在定义时赋值的变量,在之后代码中使用到,java 编译器会在之后使用的地方直接替换该变量名为实际变量值
3.final 方法不可以被子类重写,final类不可以被继承
4.匿名内部类需要引用局部变量,局部变量需要用final 声明
5.final 可以构建不可变对象,线程 安全的,如String
final 实例变量赋值:
1.在定义变量时赋值
2.在初始化代码块赋值
3.在构建器中赋值
final 类变量赋值:
1.在定义类变量时赋值
2.在静态初始化代码块中赋值
注意: final 值更改后,所有引用过该值的类都需要重新编译。
原因:final 的使已经被编译到相关类中。
public class TestStackCallBack {
public void test(final byte []data,final CountDownLatch countDownLatch ){
Thread thread = new Thread(new Runnable() {
public void run() {
try {
Thread.currentThread().sleep(10000);
byte [] x = data;
countDownLatch.countDown();
}catch (Exception e){
e.printStackTrace();
}
}
});
thread.start();
}
public static void main(String [] args){
int count = 500;
CountDownLatch countDownLatch = new CountDownLatch(count);
TestStackCallBack stack = new TestStackCallBack();
for(int i=0;i<count;i++){
byte data [] = new byte[1024*1024];
stack.test(data,countDownLatch);
}
try {
countDownLatch.await();//等待所有线程安全,栈被回收
System.out.println("Thread finish");
System.gc();//调用GC
System.out.println("gc finish");
System.in.read();//进程不结束
}catch (Exception e){
e.printStackTrace();
}
}
}
GC情况:
线程内变量引用final 数组data:
byte数组在线程执行完成之间,一直占用堆空间,直到线程完成,GC下次触发时,byte数组被回收。
[GC [PSYoungGen: 48999K->7275K(57344K)] 48999K->45171K(186880K), 0.0179709 secs] [Times: user=0.03 sys=0.01, real=0.02 secs]
[GC [PSYoungGen: 56913K->7096K(107008K)] 94810K->92097K(236544K), 0.0161681 secs] [Times: user=0.00 sys=0.05, real=0.02 secs]
[Full GC [PSYoungGen: 7096K->0K(107008K)] [ParOldGen: 85001K->91968K(200192K)] 92097K->91968K(307200K) [PSPermGen: 3151K->3150K(21504K)], 0.0275877 secs] [Times: user=0.08 sys=0.00, real=0.03 secs]
[GC [PSYoungGen: 98639K->7296K(107008K)] 190608K->189378K(307200K), 0.0268776 secs] [Times: user=0.02 sys=0.03, real=0.03 secs]
[Full GC [PSYoungGen: 7296K->0K(107008K)] [ParOldGen: 182082K->189269K(363520K)] 189378K->189269K(470528K) [PSPermGen: 3150K->3150K(21504K)], 0.0238669 secs] [Times: user=0.08 sys=0.00, real=0.02 secs]
[GC [PSYoungGen: 98760K->7296K(172544K)] 288030K->287703K(536064K), 0.0294232 secs] [Times: user=0.08 sys=0.02, real=0.03 secs]
[Full GC [PSYoungGen: 7296K->0K(172544K)] [ParOldGen: 280407K->287598K(501248K)] 287703K->287598K(673792K) [PSPermGen: 3150K->3150K(21504K)], 0.0550028 secs] [Times: user=0.09 sys=0.00, real=0.06 secs]
[GC [PSYoungGen: 164338K->7296K(189952K)] 451937K->451569K(691200K), 0.0410610 secs] [Times: user=0.05 sys=0.09, real=0.04 secs]
[Full GC [PSYoungGen: 7296K->0K(189952K)] [ParOldGen: 444273K->451478K(743424K)] 451569K->451478K(933376K) [PSPermGen: 3150K->3150K(21504K)], 0.0118656 secs] [Times: user=0.00 sys=0.01, real=0.01 secs]
Thread finish
[GC [PSYoungGen: 61801K->32K(258560K)] 513280K->451510K(1001984K), 0.0067009 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
[Full GC [PSYoungGen: 32K->0K(258560K)] [ParOldGen: 451478K->813K(743424K)] 451510K->813K(1001984K) [PSPermGen: 3156K->3156K(21504K)], 0.0278115 secs] [Times: user=0.05 sys=0.00, real=0.03 secs]
gc finish
package app.iframe.temp;
public class TestStackCallBack {
public void test(final byte []data,final CountDownLatch countDownLatch ){
Thread thread = new Thread(new Runnable() {
public void run() {
try {
Thread.currentThread().sleep(10000);
//byte [] x = data;不引用final
countDownLatch.countDown();
}catch (Exception e){
e.printStackTrace();
}
}
});
thread.start();
}
public static void main(String [] args){
int count = 500;
CountDownLatch countDownLatch = new CountDownLatch(count);
TestStackCallBack stack = new TestStackCallBack();
for(int i=0;i<count;i++){
byte data [] = new byte[1024*1024];
stack.test(data,countDownLatch);
}
try {
countDownLatch.await();
System.out.println("Thread finish");
System.gc();
System.out.println("gc finish");
System.in.read();
}catch (Exception e){
e.printStackTrace();
}
}
}
GC 情况:byte数组在线程执行完成之就被回收了。(线程内未引用final 数组data)
[GC [PSYoungGen: 48999K->1144K(57344K)] 48999K->1152K(186880K), 0.0020980 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC [PSYoungGen: 50782K->888K(57344K)] 50790K->896K(186880K), 0.0027967 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC [PSYoungGen: 50387K->952K(57344K)] 50395K->960K(186880K), 0.0091948 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
[GC [PSYoungGen: 50332K->976K(107008K)] 50340K->984K(236544K), 0.0022097 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC [PSYoungGen: 99580K->1064K(107008K)] 99588K->1072K(236544K), 0.0091775 secs] [Times: user=0.05 sys=0.00, real=0.01 secs]
[GC [PSYoungGen: 99566K->1040K(200192K)] 99574K->1048K(329728K), 0.0016906 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Thread finish
[GC [PSYoungGen: 127252K->64K(200192K)] 127260K->900K(329728K), 0.0024059 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC [PSYoungGen: 64K->0K(200192K)] [ParOldGen: 836K->816K(129536K)] 900K->816K(329728K) [PSPermGen: 3157K->3156K(21504K)], 0.0284770 secs] [Times: user=0.05 sys=0.00, real=0.03 secs]
gc finish
public class TestStackCallBack {
public void test(final byte []data,final CountDownLatch countDownLatch ){
Thread thread = new Thread(new Runnable() {
public void run() {
try {
Thread.currentThread().sleep(10000);
byte [] x = data;
countDownLatch.countDown();
}catch (Exception e){
e.printStackTrace();
}
}
});
thread.start();
}
public static void main(String [] args){
int count = 50000;
CountDownLatch countDownLatch = new CountDownLatch(count);
TestStackCallBack stack = new TestStackCallBack();
for(int i=0;i<count;i++){
byte data [] = new byte[1024*1024];
stack.test(data,countDownLatch);
}
try {
countDownLatch.await();
System.out.println("Thread finish");
System.gc();
System.out.println("gc finish");
System.in.read();
}catch (Exception e){
e.printStackTrace();
}
}
}
GC情况:增加循环次数,byte [] 数据越增越多,线程未完成,线程内变量引用fina data,造成byte []不能被
gc回收,堆内存溢出。
[GC [PSYoungGen: 48999K->7307K(57344K)] 48999K->45203K(186880K), 0.0134559 secs] [Times: user=0.03 sys=0.02, real=0.01 secs]
[GC [PSYoungGen: 56945K->7648K(107008K)] 94842K->92061K(236544K), 0.0146417 secs] [Times: user=0.03 sys=0.01, real=0.01 secs]
[Full GC [PSYoungGen: 7648K->0K(107008K)] [ParOldGen: 84413K->91968K(201728K)] 92061K->91968K(308736K) [PSPermGen: 3151K->3150K(21504K)], 0.0313719 secs] [Times: user=0.06 sys=0.00, real=0.03 secs]
[GC [PSYoungGen: 98639K->7296K(107008K)] 190608K->189378K(308736K), 0.0239866 secs] [Times: user=0.00 sys=0.05, real=0.02 secs]
[Full GC [PSYoungGen: 7296K->0K(107008K)] [ParOldGen: 182081K->189268K(373248K)] 189378K->189268K(480256K) [PSPermGen: 3150K->3150K(21504K)], 0.0318223 secs] [Times: user=0.11 sys=0.00, real=0.03 secs]
[GC [PSYoungGen: 98760K->7296K(162816K)] 288029K->287702K(536064K), 0.0267895 secs] [Times: user=0.02 sys=0.05, real=0.03 secs]
[Full GC [PSYoungGen: 7296K->0K(162816K)] [ParOldGen: 280406K->287597K(516608K)] 287702K->287597K(679424K) [PSPermGen: 3150K->3150K(21504K)], 0.0299845 secs] [Times: user=0.03 sys=0.03, real=0.03 secs]
[GC [PSYoungGen: 155093K->7296K(185856K)] 442691K->442352K(702464K), 0.0416369 secs] [Times: user=0.05 sys=0.06, real=0.04 secs]
[Full GC [PSYoungGen: 7296K->0K(185856K)] [ParOldGen: 435056K->442259K(751104K)] 442352K->442259K(936960K) [PSPermGen: 3150K->3150K(21504K)], 0.0336251 secs] [Times: user=0.05 sys=0.00, real=0.03 secs]
[GC [PSYoungGen: 177507K->52352K(274944K)] 619766K->619542K(1026048K), 0.0447134 secs] [Times: user=0.05 sys=0.06, real=0.05 secs]
[GC [PSYoungGen: 273828K->66689K(289280K)] 841017K->840729K(1063424K), 0.0642865 secs] [Times: user=0.08 sys=0.17, real=0.07 secs]
[Full GC [PSYoungGen: 66689K->66656K(289280K)] [ParOldGen: 774040K->774038K(1169920K)] 840729K->840694K(1459200K) [PSPermGen: 3151K->3151K(21504K)], 0.1429498 secs] [Times: user=0.30 sys=0.00, real=0.14 secs]
[GC [PSYoungGen: 288032K->83169K(414720K)] 1062071K->1062010K(1584640K), 0.0784695 secs] [Times: user=0.09 sys=0.17, real=0.08 secs]
[Full GC [PSYoungGen: 83169K->0K(414720K)] [ParOldGen: 978841K->1061936K(1520128K)] 1062010K->1061936K(1934848K) [PSPermGen: 3151K->3151K(21504K)], 0.0354499 secs] [Times: user=0.09 sys=0.05, real=0.04 secs]
[GC [PSYoungGen: 330942K->100481K(432128K)] 1392879K->1392821K(1952256K), 0.0796893 secs] [Times: user=0.06 sys=0.20, real=0.08 secs]
[Full GC [PSYoungGen: 100481K->0K(432128K)] [ParOldGen: 1292340K->1392770K(1909248K)] 1392821K->1392770K(2341376K) [PSPermGen: 3152K->3152K(21504K)], 0.0423679 secs] [Times: user=0.03 sys=0.05, real=0.04 secs]
[GC [PSYoungGen: 331001K->118913K(543232K)] 1723771K->1723655K(2452480K), 0.0865536 secs] [Times: user=0.11 sys=0.14, real=0.09 secs]
[GC [PSYoungGen: 542039K->139506K(563712K)] 2146780K->2146685K(2571264K), 0.1873270 secs] [Times: user=0.19 sys=0.22, real=0.19 secs]
[Full GC [PSYoungGen: 139506K->139454K(563712K)] [ParOldGen: 2007179K->2007171K(2075136K)] 2146685K->2146626K(2638848K) [PSPermGen: 3153K->3153K(21504K)], 0.3063017 secs] [Times: user=0.53 sys=0.00, real=0.31 secs]
[Full GC [PSYoungGen: 562579K->494844K(563712K)] [ParOldGen: 2007171K->2074796K(2075136K)] 2569751K->2569641K(2638848K) [PSPermGen: 3170K->3170K(21504K)], 0.1709338 secs] [Times: user=0.31 sys=0.08, real=0.17 secs]
[Full GCException in thread "main" java.lang.OutOfMemoryError: Java heap space
at app.iframe.temp.TestStackCallBack.main(TestStackCallBack.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
[PSYoungGen: 494844K->494844K(563712K)] [ParOldGen: 2074796K->2074773K(2075136K)] 2569641K->2569618K(2638848K) [PSPermGen: 3170K->3170K(21504K)], 0.4682238 secs] [Times: user=0.80 sys=0.00, real=0.47 secs]
Heap
PSYoungGen total 563712K, used 495229K [0x00000007c0a80000, 0x00000007f8680000, 0x0000000800000000)
eden space 423424K, 100% used [0x00000007c0a80000,0x00000007da800000,0x00000007da800000)
from space 140288K, 51% used [0x00000007da800000,0x00000007dee1f6b0,0x00000007e3100000)
to space 164352K, 0% used [0x00000007ee600000,0x00000007ee600000,0x00000007f8680000)
ParOldGen total 2075136K, used 2074773K [0x0000000742000000, 0x00000007c0a80000, 0x00000007c0a80000)
object space 2075136K, 99% used [0x0000000742000000,0x00000007c0a256f0,0x00000007c0a80000)
PSPermGen total 21504K, used 3201K [0x000000073ce00000, 0x000000073e300000, 0x0000000742000000)
object space 21504K, 14% used [0x000000073ce00000,0x000000073d120750,0x000000073e300000)
Process finished with exit code 1