java大對象,Java大對象重複賦值內存

本文目錄一覽:

Java函數是否適合將大對象作為參數?尤其高並發的時候?

java是傳引用,所以大不大無所謂

只是並發的時候如果你又需要對對象做修改,那就要注意對性能影響可能很大了,這個影響是因為你需要鎖住對象確保線程安全,浪費了cpu資源,而不是因為對象大這個原因,也就是說如果你對象雖然大,但是你線程不會對它進行修改,那性能還是很高的

如何使用java讀取大對象

只用到了readLine()方法,但理所當然任何DataInputStream方法都可以採用。一旦抵達文件末尾,readLine()就會返回一個null(空),以便中止並退出while循環。

關於JAVA~~~~ 如何將圖片等大對象存入ORACLE中~~求詳解!(代碼)

插入圖片/文本(blob /clob)到oracle資料庫(引用)

我們在寫OA的時候經常遇到的問題就是員工圖片檔案的儲存問題,解決這個問題有兩個方法,

1.JSP/html頁面裡面讀取web伺服器上的圖片,也就是把圖片放到(上傳)到web 伺服器上,然後用html 語句讀取:

img src=” 絕對或相對路徑 ” border=”0″ /

2.就是上傳到資料庫裡面(oracle).關於oracle 資料庫,它支持blob, 和clob, 分別對應著圖片和文本(長字元串)操作

由於性能原因,我們還是要採用第二種方法,而且存到資料庫裡面比較容易管理,是吧?

首先,我們要解決上傳問題,這裡採用普遍使用的apache commons 組件裡面的FileUpload class.

具體步驟如:

DiskFileUpload dfu=new DiskFileUpload();

dfu.setSizeMax(100000000);

dfu.setSizeThreshold(100000);

dfu.setRepositoryPath(“f:\\public”);

try{

List fileItems=dfu.parseRequest(request);

Iterator i=fileItems.iterator();

while(i.hasNext()){

FileItem fi=(FileItem)i.next();

if(!fi.isFormField()){

name=fi.getName();

size=fi.getSize();

if((name==null||name.equals(“”))size==0)

continue;

}

name=fi.getName();

size=fi.getSize();

(InputStream)is=fi.getInputStream();

}

上面的代碼是web伺服器接受上傳的代碼,參考文件已經在我上篇寫的上傳文本文件里給出,今天,終於想明白了:

dfu.setRepositoryPath(“f:\\public”); 的意思

原來是轉義字元也就是說\n\t等而要列印反斜杠要用\\,其實這個問題原先已經知道,可是由於經驗沒有寫過圖片上傳處理什麼的,覺得很高深,也很可怕,哈哈,心裡有點畏懼.看來基礎的東西,那怕一點點小細節也很重要,接著還有下面的java IO 問題.剛才讀core java 的時候突然發現在講io的時候特意提醒了這個問題,可是我沒有注意!

通過上面的代碼已經實現文件上傳了.然後,我們要實現JDBC數據源鏈接,目的是要把數據插入到oracle.

Context ctx=new InitialContext();

DataSource ds=(DataSource)ctx.lookup(“jdbc/asdbCoreDS”);

conn=ds.getConnection();

conn.setAutoCommit(false);

關於要import java.sql.* javax.sql.* java.naming.* 不再詳細敘述了

接著根據很有用的一篇文章的提示,插入blob類型一定要先1.插入一個空的

String insert=” insert into uploadpicture “+

” values(?, empty_blob()) ” ;

2.然後找到這個blob的oracle 裡面的游標:

String findCursor=” select content “+

” from uploadpicture “+

” where name=? for update “;

注意這個for update(注意!!!必須加for update,這將鎖定該行,直至該行被修改完畢,保證不產生並發衝突。這裡還是難以理解,先記下來吧)

3.然後再修改

String update=” update uploadpicture “+

” set content=? “+

” where name=? “;

這裡的問號是為PreparedStatement參數處理而寫的!

寫這個程序用到了oracle.sql.BLOB class ,這個類是用來操作BLOB數據類型的

當我們通過ResultSet 對象得到

blob=(BLOB)rs.getBlob(1);

的時候我不知道如何處理了,Blob 是什麼?String, int ,long? 我現在也不明白!估計CSDN上的人也不明白,否則我發個帖子半天沒有人回答,也許是很爛,也許是太簡單了,大家不屑一顧,看來我還要繼續追趕!

不發牢騷了,回到程序里(總覺得自己的發散思維很強,看來寫程序的時候不能這樣,多虧java 是純面向對象語言,如果是過程就麻煩了)

我們如何處理這個blob 呢?回答是,不管它是什麼,直接寫入 BufferedOutputStream out1 =new BufferedOutputStream(blob.getBinaryOutputStream());

這裡是建立了緩衝寫如blob 的流(注意getBinaryOutputStream()已經不被贊成使用了,一定有更優秀的方法替代!),說到流,我到現在還有點暈,類很多,不知道究竟用哪個好!

基礎的東西非常重要,這曾經是我的口頭禪,這裡用到了流的讀入寫和寫入,有些流是從文件或其它位置上讀取位元組(如, FileInputStream),有寫流是把位元組組合成有用的數據(如, DataInputStream).我們讀取數字的時候,需要首先建議一個FileInpuStream, 然後, 再把該類的對象傳遞給DataInputStream

FileInputStream fin=new FileInputStream(「emp.dat」);

DataInputStream din=new DataInputStream(fin);//把fin傳遞給din

double s=din.readDouble();

默認情況下,流是沒有緩衝的, 如果使用緩衝就是

DataInputStream din=new DataInputStream(

new BufferedInputStream(new FileINputStream(「emp.dat」)));

有了這點理解也很管用,

BufferedOutputStream out1 =new BufferedOutputStream(blob.getBinaryOutputStream());

就是建立一個緩衝寫的對象到blob.注意這裡的out1 不是out,否則程序運行的時候不能列印了temp 數據了!

已經準備好如何寫了, 可是如何讀呢?

BufferedInputStream in=new BufferedInputStream(is);

在我們上傳的時候 (InputStream)is=fi.getInputStream();

讀取圖片為輸入的流.保存為is 對象,然後就用到這裡了,準備好了讀和寫了,我們開始幹活:

int c;

while((c=in.read())!=-1) {out1.write(c);}

in.close();

out1.close();

通過緩衝一個個讀數據,然後一個個寫數據.-1 為文件的末尾,

最後當讀寫完成後我們要關閉讀寫對象!

程序分析就是這樣,以後還要對此問題進行研究,最後還要注意,

%@ page contentType=”image/jpeg;charset=GBK”%

不是

%@ page contentType=”text/html;charset=GBK”%

否則是以文字顯示圖片—亂碼.

這裡研究了上傳圖片到oralce 裡面的程序,關於顯示還要麻煩一點,藉助資料我實現了,明天再研究一下.

//插入上傳圖片到資料庫

%@ page contentType=”text/html;charset=GBK”%

%@ page import=”java.util.*”%

%@ page import=”java.io.*”%

%@ page import=”org.apache.commons.*”%

%@ page import=”org.apache.commons.fileupload.*”%

%@ page import=”java.sql.*”%

%@ page import=”javax.sql.*”%

%@ page import=”javax.naming.*”%

%@ page import=”oracle.sql.*”%

html

head

meta http-equiv=”Content-Type” content=”text/html; charset=GBK”

titlegetPicture.jsp/title

/head

body

%

request.setCharacterEncoding(“GBK”);

String name=null;

long size=0;

Connection conn=null;

String insert=” insert into uploadpicture “+

” values(?, empty_blob()) ” ;

String findCursor=” select content “+

” from uploadpicture “+

” where name=? for update “;

String update=” update uploadpicture “+

” set content=? “+

” where name=? “;

BLOB blob=null;

InputStream is=null;

DiskFileUpload dfu=new DiskFileUpload();

dfu.setSizeMax(100000000);

dfu.setSizeThreshold(100000);

dfu.setRepositoryPath(“f:\\public”);

try{

List fileItems=dfu.parseRequest(request);

Iterator i=fileItems.iterator();

while(i.hasNext()){

FileItem fi=(FileItem)i.next();

if(!fi.isFormField()){

name=fi.getName();

size=fi.getSize();

if((name==null||name.equals(“”))size==0)

continue;

}

name=fi.getName();

size=fi.getSize();

is=fi.getInputStream();

}

Context ctx=new InitialContext();

DataSource ds=(DataSource)ctx.lookup(“jdbc/asdbCoreDS”);

conn=ds.getConnection();

conn.setAutoCommit(false);

//step 1

PreparedStatement ps=conn.prepareStatement(insert);

ps.setString(1, name);

int a=ps.executeUpdate();

if(a0)

out.println(“insert success!”+”br”);

//step 2

ps=conn.prepareStatement(findCursor);

ps.setString(1, name);

ResultSet rs=ps.executeQuery();

while(rs.next())

{

blob=(BLOB)rs.getBlob(1);

out.println(“find cursor success!”+”br”);

out.println(“cursor :”+blob+”br”);

//step 3

ps=conn.prepareStatement(update);

ps.setBlob(1, blob);

ps.setString(2, name);

ps.executeUpdate();

ps.close();

BufferedOutputStream out1 =new BufferedOutputStream(blob.getBinaryOutputStream());

BufferedInputStream in=new BufferedInputStream(is);

int c;

while((c=in.read())!=-1) {out1.write(c);}

in.close();

out1.close();

out.println(“update success!”+”br”);}

conn.commit();

}

catch(SQLException se)

{se.printStackTrace();}

catch(FileUploadException fue)

{fue.printStackTrace();}

%

/body

/html

//顯示資料庫裡面的圖片

%@ page contentType=”image/jpeg;charset=GBK”%

%@ page import=”java.sql.*”%

%@ page import=”javax.sql.*”%

%@ page import=”javax.naming.*”%

%@ page import=”java.io.*”%

%@ page import=”com.sun.image.codec.jpeg.*”%

%@ page import=”javax.imageio.*”%

%@ page import=”java.util.*”%

%@ page import=”java.awt.image.*”%

html

head

meta http-equiv=”Content-Type” content=”image/jpeg; charset=GBK”

titleshowDBImage.jsp/title

/head

body

%

String showImage=” select * “+

” from uploadpicture “+

” where name=´TXC with snow.JPG´ ” ;

Connection conn=null;

BufferedInputStream inputImage=null;

try{

Context ctx=new InitialContext();

DataSource ds=(DataSource)ctx.lookup(“jdbc/asdbCoreDS”);

conn=ds.getConnection();

Statement st=conn.createStatement();

ResultSet rs=st.executeQuery(showImage);

while(rs.next())

{

oracle.sql.BLOB blob=(oracle.sql.BLOB)rs.getBlob(“content”);

inputImage =new BufferedInputStream(blob.getBinaryStream());

/*String name=rs.getString(1);

String content=rs.getString(2);

out.println(name+”br”);*/}

BufferedImage image=null;

image=ImageIO.read(inputImage);

ServletOutputStream sos=response.getOutputStream();

JPEGImageEncoder encoder=JPEGCodec.createJPEGEncoder(sos);

encoder.encode(image);

inputImage.close();

conn.commit();

}

catch(SQLException se)

{se.printStackTrace();

conn.rollback(); }

catch(IOException ie)

{ie.printStackTrace();}

%

/body

/html

jvm默認多大的對象是大對象

jvm默認多大的對象是大對象?對象的內存分配——對象優先在Eden分配

當Eden區沒有足夠空間進行分配時,虛擬機將發起一次Minor GC。

testAllocation()方法中,嘗試分配3個2MB大小和1個4MB大小的對象,在運行時通過-Xms20M、-Xmx20M、-Xmn10M這3個參數限制了Java堆大小為20MB,不可擴展,其中10MB分配給新生代,剩下的10MB分配給老年代。-XX:SurvivorRatio=8決定了新生代中Eden區與一個Survivor區的空間比例是8:1,從輸出的結果也可以清晰地看到「eden space 8192K、from space 1024K、to space 1024K」的信息,新生代總可用空間為9216KB(Eden區+1個Survivor區的總容量)。執行testAllocation()中分配allocation4對象的語句時會發生一次Minor GC,這次GC的結果是新生代6651KB變為162KB,而總內存佔用量則幾乎沒有減少(因為allocation1、allocation2、allocation3三個對象都是存活的,虛擬機幾乎沒有找到可回收的對象)。這次GC發生的原因是給allocation4分配內存的時候,發現Eden已經被佔用了6MB,剩餘空間已不足以分配allocation4所需的4MB內存,因此發生Minor GC。GC期間虛擬機又發現已有的3個2MB大小的對象全部無法放入Survivor空間(Survivor空間只有1MB大小),所以只好通過分配擔保機制提前轉移到老年代去。這次GC結束後,4MB的allocation4對象順利分配在Eden中,因此程序執行完的結果是Eden佔用4MB(被allocation4佔用),Survivor空閑,老年代被佔用6MB(被allocation1、allocation2、allocation3佔用)。

下面看看使用Parallel Scavenge收集器的情況:

沒有發生新生代GC,直接把allocation4分配到老年代上。

對象的內存分配——大對象直接進入老年代——典型的大對象

很長的字元串以及數組

對象的內存分配——大對象直接進入老年代——大對象噩夢

比遇到一個大對象更加壞的消息就是遇到一群「朝生夕滅」的「短命大對象」,經常出現大對象容易導致內存還有不少空間時就提前觸發垃圾收集以獲取足夠的連續空間來「安置」它們。

對象的內存分配——大對象直接進入老年代——原因

大於-XX:PretenureSizeThreshold設置值的對象直接在老年代分配。這樣做的目的是避免在Eden區及兩個Survivor區之間發生大量的內存複製。

PretenureSizeThreshold被設置為3MB(就是3145728,這個參數不能像-Xmx之類的參數一樣直接寫3MB),因此超過3MB的對象都會直接在老年代進行分配。

PretenureSizeThreshold參數只對Serial和ParNew兩款收集器有效,Parallel Scavenge收集器不認識這個參數,Parallel Scavenge收集器一般並不需要設置。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/231677.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-11 01:06
下一篇 2024-12-11 01:06

相關推薦

  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Bean載入過程

    Java Bean載入過程涉及到類載入器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean載入的過程。 一、類載入器 類載入器是Java虛擬機…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Python創建分配內存的方法

    在python中,我們常常需要創建並分配內存來存儲數據。不同的類型和數據結構可能需要不同的方法來分配內存。本文將從多個方面介紹Python創建分配內存的方法,包括列表、元組、字典、…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發布。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • Java判斷字元串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字元串中是否存在多個指定字元: 一、字元串遍歷 字元串是Java編程中非常重要的一種數據類型。要判斷字元串中是否存在多個指定字元…

    編程 2025-04-29
  • VSCode為什麼無法運行Java

    解答:VSCode無法運行Java是因為默認情況下,VSCode並沒有集成Java運行環境,需要手動添加Java運行環境或安裝相關插件才能實現Java代碼的編寫、調試和運行。 一、…

    編程 2025-04-29
  • Java任務下發回滾系統的設計與實現

    本文將介紹一個Java任務下發回滾系統的設計與實現。該系統可以用於執行複雜的任務,包括可回滾的任務,及時恢復任務失敗前的狀態。系統使用Java語言進行開發,可以支持多種類型的任務。…

    編程 2025-04-29

發表回復

登錄後才能評論