달력

5

« 2024/5 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
.. .. ..
예외와 오류(error)와 관련된 클래의 상속 계통도는 아래와 같다.


Throwable

-- Error // 심각한 오류 (컴파일시 확인)

-- Exception // 환경상의 잘못으로 인한 예외 (파일 없음 등)

-- RuntimeException // 프로그램상의 오류로 인한 예외


오류(error)는 시스템상의 결함이 발생하여 프로그램이 더 이상 진행하지 못할 정도의 상황이 된 것을 나타낸다. 예를들면 메모리의 부족, 클래스 없음 등이 해당된다.


Exception은 프로그램을 잘못 작성하여 발생하는 예외가 아니라 I/O 문제, 네트웍 다운, 잘못된 이름입력 등 환경이 잘못되어 발생하는 예외를 말하며 이를 확인예외(checked exception) 라고 한다. 이러한 확인예외는 항상 발생할 가능성이 있는 것이므로 이에 대한 처리 방법을 "반드시" 구현해 두어야만 한다. 확인예외의 처리방법은 프로그래머가 항상 구체적으로 기술해야 하는데 이러한 확인예외 처리방법에는 try/catch 를 이용하여 구체적으로 기술하는 방법과, 상위 메소드에게 예외발생을 알리는(throws 하는) 방법 크게 두 가지로 나눌 수 있다.


RuntimeException은 프로그램을 잘못 작성하여 발생하는 예외로서 어레이의 경계를 넘은 경우, 조건문의 처리 잘못 등이 해당된다. 이것은 프로그램을 오류없이 작성하였다면 발생하지 않게 되는 예외이므로 이러한 예외의 처리를 자바가 반드시 요구하지는 않는다. 그러나 ArithmeticException 과 같은 RuntimeException 예외는 처리해 두면 편리하다.

 

.
:
Posted by .07274.
.. .. ..

[펌] : http://agbird.egloos.com/4863601

 

 

ConcurrentHashMap vs. HashTable 이란 글에서 아래와 같은 코드는 잘못된 방법일 뿐더러 위험한 방법이라고 했습니다.

class SharedData {
private Integer intData = 0;
private Boolean boolData = false;

public int getInt() { synchronized (intData) { return intData; } }
public void setInt(int n) { synchronized (intData) { intData = n; } }
public boolean getBool() { synchronized (boolData) { return boolData; } }
public void setBool(boolean b) { synchronized (boolData) { boolData = b; } }
}

우선 잘못된 이유에 대해서 먼저 설명하자면 프로그래머의 의도와 달리 intData 나 boolData 객체는 동기화되지 않습니다. 그 이유는 setInt() 나 setBool() 함수가 호출될 때마다 락으로 사용되는 intData 나 boolData 객체가 변할 수 있는데 이런 경우 쓰레드들이 서로 다른 락에 접근하기 때문입니다. 예를 들어 다음과 같은 코드가 있다고 합시다.

public class SyncTest {
static private Object lock = new Object();

static class TestRunnable implements Runnable {
@Override
public void run() {
try {
synchronized (lock) {
System.out.println("before sleep in thread");
Thread.sleep(1000);
System.out.println("after sleep in thread");
}
} catch (Interrupted Exception e) {
}
}
}

public static void main(String[] args) {
ExecutorService threads = Executors.newFixedThreadPool(2);
threads.submit(new TestRunnable());
threads.submit(new TestRunnable());
threads.shutdown();
try {
threads.awaitTermination(1, TimeUnit.MINUTES);
} catch (InterruptedException e) {
}
System.exit(0);
}
}

위 코드를 실행시켜 보면 항상 아래처럼 출력됩니다.

before sleep in thread
after sleep in thread
before sleep in thread
after sleep in thread

그러나 위에 동기화 부분을 다음과 같이 고치면 문제가 발생합니다.

synchronized (lock) {
lock = new Object(); // assigned another object to lock
System.out.println("before sleep in thread");
Thread.sleep(1000);
System.out.println("after sleep in thread");
}

lock 객체가 동기화 블럭내에서 다른 객체로 변경되었기 때문에 이후에 다른 쓰레드에서 lock 객체에 접근하면 더이상 쓰레드간 동기화 효과가 없습니다. 자바에서 모든 객체는 레퍼런스 객체입니다. 그런데 synchronized 블럭에서 동기화를 위해 참조하는 객체는 이 레퍼런스 객체가 아니라 레퍼런스 객체가 참조하고 있는 실제 객체입니다. 따라서 비록 같은 lock 객체라 하더라도 이 객체가 참조하는 실제 객체가 바뀌었기 때문에 쓰레드간 동기화는 깨지고 맙니다.

이 글의 처음에 소개된 SharedData 클래스의 잘못된 점은 intData 나 boolData 가 setter 메소드에서 다른 값이 할당되는 순간 Auto boxing 에 의해 다른 객체를 참조하기 때문입니다. 그러므로 이 시점에 다른 쓰레드가 synchronized 블럭에 접근하게 되더라도 다른 객체에 접근하기 때문에 락이 해제될때까지 기다리지 않습니다. 따라서 어떤 경우라도 synchronized 블럭 내에서 락 객체의 참조값을 변경하지 말아야 합니다. 보통 이런 실수를 할 소지는 적습니다만 SharedData 클래스 예처럼 Auto boxing 이 발생하는 Integer, Boolean, Long 등과 같은 클래스를 사용할 때는 자칫 착각할 수 있습니다.

이제 SharedData 클래스의 동기화 방식이 위험한 이유에 대해서 설명하겠습니다. 우선 아래 코드를 보시기 바랍니다.

public class SyncTest {
static private String lock = "This is a lock;

static class TestRunnable implements Runnable {
@Override
public void run() {
try {
synchronized (lock) {
System.out.println("before sleep in thread");
Thread.sleep(1000);
System.out.println("after sleep in thread");
}
} catch (Interrupted Exception e) {
}
}
}

public static void main(String[] args) {
// 이전 코드와 동일...
}
}

위 코드가 제대로 동작할까요?
- 예 그렇습니다.
그렇다면 좋은 방법일까요?
- 아뇨 그렇지 않습니다(Joshua Bloch 말투 좀 흉내내 봤습니다).

그러면 왜 좋은 방법이 아닐까요? 왜냐하면 String 객체를 락으로 사용하는 것은 예기치 않은 dead lock 을 발생시키기 때문입니다. 예를 들어 아래 코드를 보시죠.

public class BadLockSample {
static void main(String[] args) throws Exception {
String lock = "This is a lock";
synchronized (lock) {
Future<String> future = Executors.newSingleThreadExecutor().submit(new Callable<String>() {
@Override
public String call() throws Exception {
String anotherLock = "This is a lock";
synchronized (anotherLock) {
return "Result";
}
}
});
System.out.println(future.get());
}
}
}

위 코드에서 메인 쓰레드와 Callable 클래스가 호출되는 쓰레드는 서로 다른 락 객체를 사용하고 있습니다만 실행시켜보면 데드락이 발생하여 프로그램이 종료하지 않습니다. 왜 그럴까요? 그 이유는 자바에서 문자열을 다른 객체와 달리 특별한 방식으로 관리 하기 때문입니다. 자바는 메모리를 절약하기 위해 컴파일 시점에 평가 가능한 문자열에 대해서 영구 메모리에 문자열을 저장하며 이 문자열을 참조하는 String 객체들은 명시적으로 new String() 을 사용해서 객체를 생성하지 않는한 같은 문자열일 경우 동일한 객체를 참조하게 됩니다(혹은 String.intern() 메소드를 호출하면 명시적으로 이런 처리가 가능합니다).
결국 위에서 lock 과 anotherLock 은 다른 레퍼런스 객체이지만 동일한 상수 문자열을 참조하기 때문에 사실 동일한 객체나 마찬가지입니다. 따라서 위 프로그램의 메인 쓰레드와 Callable 쓰레드는 같은 락을 획득하려고 경쟁하기 때문에 데드락이 발생합니다.
그런데 이게 SharedData 클래스와 무슨 관계일까요? SharedData 에서는 String 이 아니라 Integer 와 Boolean 객체를 사용했고 이들 클래스는 Auto Boxing 에 의해 primitive type 값을 자동으로 해당 타입에 맞는 객체로 생성해줍니다. 따라서 String 에서처럼 같은 객체를 참조할 일은 없을 듯 싶습니다.
하지만 실제로는 그렇지 않습니다. 왜냐하면 Integer 나 Boolean 같은 Wrapping type class 들은 성능 향상을 위해 몇몇 값들에 대해서는 매번 객체를 새로 생성하는 것이 아니라 미리 만들어 놓은 객체를 재 사용하기 때문입니다(이런 방식을 Flyweight pattern 이라고 합니다).
따라서 SharedData 객체를 만약 아래와 같이 사용하게 되면 데드락이 발생합니다.

public static void main(String[] args) {
static void main(String[] args) throws Exception {
Integer lock= 0;
synchronized (lock) {
Future<String> future = Executors.newSingleThreadExecutor().submit(new Callable<String>() {
@Override
public String call() throws Exception {
return new SharedData().getInt();
}
});
System.out.println(future.get());
}
}
}

결론적으로 값 객체를 직접 락으로 사용하지 말아야 합니다. 꼭 값 객체를 별도의 락으로 동기화시키려면 java.util.concurrent.lock.ReentrantLock 같은 락 전용 클래스 객체를 사용하는 것이 좋습니다.

p.s. 노파심에서 언급하는 건데...혹여라도 ReentrantLock 을 아래처럼 사용하지는 마세요...

Lock lock = new ReentrantLock();
synchronized (lock) {
....
}

java.util.concurrent.lock.Lock 관련 클래스들의 올바른 사용법은 다음과 같습니다.

Lock lock = new ReentrantLock();
lock.lock();
try {
....
} finally {
lock.unlock();
}

 

.
:
Posted by .07274.
2013. 1. 21. 15:24

[펌] Java File Writing 성능 비교 I.lib()/I.lib(Java)2013. 1. 21. 15:24

.. .. ..

[펌] : http://bcho.tistory.com/288

 

JAPM을 업그레이드 할까 싶어서 Log Writing 부분을 개선하고자 해서

File Writing을 어떻게 하는 것이 제일 빠를까 테스트를 해봤다.
크게 아래 케이스인데.

1. FileWriter fw = new FileWriter(LOG_HOME+"writer.log");
2. BufferedWriter bw = new BufferedWriter(new FileWriter(LOG_HOME+"writer.log"));
3. FileOutputStream fos = new FileOutputStream(LOG_HOME+"outputstream.log");
4. BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream(LOG_HOME+"bufferedoutputstream.log"));
5. FileChannel fc =(new FileOutputStream(new File(LOG_HOME+"filechannel.log"))).getChannel(); + Byte Buffer 매번 생성
6. FileChannel fc =(new FileOutputStream(new File(LOG_HOME+"filechannel.log"))).getChannel(); + ByteBuffer 재사용

테스트의 정확성을 위해서 측정중에 GC가 발생하지 않도록 NewSize와 HeapSize를 크게 해놓고 테스트를 하였다. Vm 옵션은 -XX:NewSize=480m -ms768m -mx768m -verbosegc 이다.
환경 : Windows XP, Sun JVM 1.5, Centrio VPro Dual core, IBM Thinkpad X61s

결과는 다음과 같다.
1K 2K 5K 10K 50K
FileWriter 31 32 94 203 1281
FileWriter + BufferedWriter 15 31 94 188 1000
FileOutputStream 32 47 109 188 1063
FileOutputStream + BufferedOutputStream 31 47 109 203 1578
FileChannel 47 63 109 219 2906
FileChannel + Byte Buffer 재사용 31 47 188 250 2766

(해당 레코드를 1000번씩 write)

예상하기로는 NIO의 FileChannel이 가장 빠를것이라 생각했는데, 의외로 FileWrite와 FileOutputStream의 성능이 높게 나왔다. NIO의 경우 JVM 벤더에 종속성이 있겠지만 이런 결과가 나오는것은 약간 의외였다.
오히려 프로그래밍 기법을 내서 FileChannel을 사용할 경우 최대 3배까지 성능이 나쁜 경우가 올 수 있으니. 이런건 차라리 모르는게 나을 수 도 있겠다~~ 싶다.. ^^

BufferedWriter등의 경우 GC를 유발하는 문제가 있을 수 있기 때문에 또 다른 성능 저하 요인이 될 수 는 있겠지만, 현재까지 테스트 결과로는 Windows Platform에서는 FileWriter + BufferedWriter의 경우가 성능이 제일 좋은것 같다.
아래는 테스트에 사용한 소스 코드
==
package bcho.filewriter.test;

import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import junit.framework.TestCase;

public class FileWriterTest extends TestCase {
final static int loop = 1000;
final static String LOG_HOME="c:/temp/";
static String LOG_STRING="";
static {
}
public void testSuite() throws Exception{
int stringSize[]={100,200,500,1000,5000};
for(int i=0;i<stringSize.length;i++){
LOG_STRING="";
for(int j=0;j<stringSize[i];j++) LOG_STRING+="1234567890";
log(stringSize[i]+"0 bytes");
testFileWriter();
System.gc();
testBufferedWriter();
System.gc();
testFileOutputStream();
System.gc();
testFileBufferedOutputStream();
System.gc();
testFileChannel();
System.gc();
testFileChannelOneBuffer();
System.gc();
}
}
public static void log(String str){
System.out.println(str);
}
// java.io.FileWriter
private void testFileWriter() throws Exception {
FileWriter fw = new FileWriter(LOG_HOME+"writer.log");
long st = Timer.getCurrentTime();
for(int i =0;i<loop;i++){
fw.write(LOG_STRING);
}
log("FileWriter :"+Timer.getElapsedTime(st) +"ms");
fw.close();
}
// java.io.BufferedWriter
private void testBufferedWriter() throws Exception {
BufferedWriter bw = new BufferedWriter(new FileWriter(LOG_HOME+"writer.log"));
long st = Timer.getCurrentTime();
for(int i =0;i<loop;i++){
bw.write(LOG_STRING);
}
log("BufferedWriter :"+Timer.getElapsedTime(st) +"ms");
bw.close();
}
// java.io.FileOutputStream
private void testFileOutputStream() throws Exception{
FileOutputStream fos = new FileOutputStream(LOG_HOME+"outputstream.log");
long st = Timer.getCurrentTime();
for(int i=0;i<loop;i++){
byte[] buf = LOG_STRING.getBytes();
fos.write(buf);
}
log("FileOutputStream :"+Timer.getElapsedTime(st) +"ms");
fos.close();
}
// java.io.FileOutputStream
// + java.io.BufferedOutputStream
private void testFileBufferedOutputStream() throws Exception{
BufferedOutputStream fos =
new BufferedOutputStream(
new FileOutputStream(LOG_HOME+"bufferedoutputstream.log"));
long st = Timer.getCurrentTime();
for(int i=0;i<loop;i++){
byte[] buf = LOG_STRING.getBytes();
fos.write(buf);
}
log("FileBufferedOutputStream :"+Timer.getElapsedTime(st) +"ms");
fos.close();
}
private void testFileChannel() throws Exception {
FileChannel fc =(new FileOutputStream(new File(LOG_HOME+"filechannel.log"))).getChannel();
long st = Timer.getCurrentTime();
for(int i=0;i<loop;i++){
byte[] buf = LOG_STRING.getBytes();
ByteBuffer bytebuffer = ByteBuffer.allocate(buf.length);
bytebuffer.put(buf);
bytebuffer.flip();
fc.write(bytebuffer);
}
log("FileChannel :"+Timer.getElapsedTime(st) +"ms");
fc.close();
}
private void testFileChannelOneBuffer() throws Exception {
FileChannel fc =(new FileOutputStream(new File(LOG_HOME+"filechannelonebuf.log"))).getChannel();
int BUF_SIZE=1000;
long st = Timer.getCurrentTime();
ByteBuffer bytebuffer = ByteBuffer.allocate(BUF_SIZE);
for(int i=0;i<loop;i++){
byte[] buf = LOG_STRING.getBytes();
int offset=0;
int length= buf.length;
while(offset < length){
int chunkSize = BUF_SIZE > length-offset ? length-offset-1 : BUF_SIZE;
bytebuffer.put(buf, offset, chunkSize);
bytebuffer.flip();
offset+=BUF_SIZE;
fc.write(bytebuffer);
bytebuffer.clear();

}
}
log("FileChannel with reusing buffer:"+Timer.getElapsedTime(st) +"ms");
fc.close();
}


}

 

.
:
Posted by .07274.
2013. 1. 15. 17:41

BlockingQueue I.lib()/I.lib(Java)2013. 1. 15. 17:41

.. .. ..

3중 1번 클레스

package concurent;

import java.util.concurrent.*;

public class blockingQuere11 {
public static void main(String[] args) {
BlockingQueue<String> drop = new ArrayBlockingQueue(1, true);
(new Thread(new blockingQuere13(drop))).start();
(new Thread(new blockingQuere12(drop))).start();
}
}

3중 2번 클레스

package concurent;

import java.util.*;
import java.util.concurrent.*;

class blockingQuere12 implements Runnable{

private BlockingQueue<String> drop;

public blockingQuere12(BlockingQueue<String> d) {
this.drop = d; }

public void run(){
try{
String msg = null;

while (!((msg = drop.take()).equals("DONE")))
System.out.println("out : "+ System.currentTimeMillis() + msg);

}catch (InterruptedException intEx){
System.out.println("Interrupted! " + "Last one out, turn out the lights!");
}
}
}

3중 3클래스

package concurent;

import java.util.*;
import java.util.concurrent.*;

public class blockingQuere13 implements Runnable {

private BlockingQueue<String> drop;
List<String> messages = Arrays.asList("1111", "2222",
"3333", "44444","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25");

public blockingQuere13(BlockingQueue<String> d) {
this.drop = d;
}

public void run() {
try {
for (String s : messages){
drop.put(s);
System.out.println("i n : "+ System.currentTimeMillis() + s);
}
drop.put("DONE");
} catch (InterruptedException intEx) {
System.out.println("Interrupted! "+ "Last one out, turn out the lights!");
}
}
}

결과값

out : 13582386103091111
i n : 13582386103091111
out : 13582386103092222
i n : 13582386103092222
out : 13582386103093333
i n : 13582386103093333
out : 135823861030944444
i n : 135823861030944444
out : 13582386103095
i n : 13582386103095
out : 13582386103096
i n : 13582386103096
out : 13582386103107
i n : 13582386103107
out : 13582386103108
i n : 13582386103108
out : 13582386103109
i n : 13582386103109
out : 135823861031010
i n : 135823861031010
out : 135823861031011
i n : 135823861031011
out : 135823861031012
i n : 135823861031012
out : 135823861031013
i n : 135823861031013
out : 135823861031014
i n : 135823861031014
out : 135823861031015
i n : 135823861031015
out : 135823861031016
i n : 135823861031016
out : 135823861031017
i n : 135823861031017
out : 135823861031018
i n : 135823861031118
out : 135823861031119
i n : 135823861031119
out : 135823861031120
i n : 135823861031120
out : 135823861031121
i n : 135823861031121
out : 135823861031122
i n : 135823861031122
out : 135823861031123
i n : 135823861031123
out : 135823861031124
i n : 135823861031124
out : 135823861031125
i n : 135823861031125


.
:
Posted by .07274.
.. .. ..

Thread 를 테스트 해보았다.

 

1.

 

Thread serverThread = Thread.currentThread();

 

System.out.println("Name : " + serverThread.getName());

 

결과값은 Main 이 나온다. 기본적으로 Java 의 Main 을 실행시키면 Main 은 Thread로 실행되기 때문이다.

 

2.    

 

this.serverThread.interrupt();

Thread.sleep(2000);

 

결과는 sleep interrupt 라는 Exception 이 나온다. 아마도 interrupt 라는 명령은 더이상 main Thread(메서드)

 

가 추가 Thread(sleep 스레드 건 부분) 를 생성할수 없게 한듯 하다.

 

3.

this.serverThread.join();

System.out.println("Hello");

 

결과는 무한 대기를 탄다. 이유는 join() 을 실행하면 main 메서드가 끝나기를 기다렸다가(락) 지정 스레드(main)가

 

끝이 나아 다음으로 진행하기 때문이다. (이부분은 테스트로 확인됨.)

'I.lib() > I.lib(Java)' 카테고리의 다른 글

[펌] Java File Writing 성능 비교  (0) 2013.01.21
BlockingQueue  (0) 2013.01.15
[암호화] 메시지 다이제스트(Message Digest)  (0) 2012.07.06
base64 인코딩 & 디코딩 원리  (0) 2012.07.02
dwr 사용방법  (0) 2012.03.22
.
:
Posted by .07274.
2012. 11. 27. 11:52

모바일 디스플레이 화면 변경 I.lib()/I.lib(Android)2012. 11. 27. 11:52

.. .. ..

[펌] : http://android.elex.pe.kr/dev-guide/android-web-app/mobile-web-page

 

 

모바일 장치의 화면은 데스크탑의 모니터보다 작습니다.또한 화면의 크기나 해상도도 다양하기 때문에 브라우저에게 적당한 화면 크기를 알려줘야 합니다.이를 위해 HTML문서의 <head>요소안에 다음과 같이 <meta>요소를 한 줄 추가해야 합니다.

<head>
<title>
모바일 </title>
<meta name="viewport" content="width=device-width, user-scalable=no" />
</head>

<meta>요소의 name속성값은 “viewport”이며content속성 값은 다양하게 설정할 수 있습니다.

<meta name="viewport"
content="
height = [pixel_value | device-height] ,
width = [pixel_value | device-width ] ,
initial-scale = float_value ,
minimum-scale = float_value ,
maximum-scale = float_value ,
user-scalable = [yes | no] ,
target-densitydpi = [dpi_value | device-dpi | high-dpi | medium-dpi | low-dpi]
" />

heightwidth는 문서 작성시에 가정한 픽셀 크기를 지정하거나device-height또는 device-width를 지정해서 장치의 전체 크기를 사용할 수 있습니다.

문서 작성시에 가로폭을 320px로 가정하고 작업했다면 다음과 같은 메타데이터를 사용할 수 있습니다.

<meta name="viewport" content="width=320" />

문서가 가변적인 너비로 작성되었다면 다음과 같은 메타데이터를 사용해서 장치의 크기에 맞는 폭을 갖도록 지정할 수 있습니다.

<meta name="viewport" content="width=device-width" />

initial-scale, minimum-scale, maximun-scale, user-scalable을 지정해서 화면의 줌(zoom)을 지정할 수 있습니다.initial-scale은 페이지 로딩시의 크기이고,minimum-scale은 최소 크기,maximun-scale은 최대 크기이며,각각의 값은 화면 크기의 비율을 부동소수값으로 지정합니다.user-scalableyes또는 no를 지정해서 사용자가 화면 크기를 확대/축소할 수 있는지를 지정합니다.

화면의 픽셀 밀도를 지정하려면 원하는 dpi값을 지정하거나 device-dpi, high-dpi, medium-dpi, low-dpi 등의 값을 지정하면 됩니다.

화면 픽셀 밀도에 따라 별도의CSS파일을 구성하려면 <link>media속성을 사용해서 다음과 같이 할 수 있습니다.

<link rel="stylesheet" 
media="screen and (-webkit-device-pixel-ratio: 1.5)"
href="hdpi.css" />
<link
rel="stylesheet"
media="screen and (-webkit-device-pixel-ratio: 1.0)"
href="mdpi.css" />
<link
rel="stylesheet"
media="screen and (-webkit-device-pixel-ratio: 0.75)"
href="ldpi.css" />

자바스크립트에서는 다음과 같은 방식으로 처리를 할 수 있습니다.

if (window.devicePixelRatio == 1.5) {
alert("
고밀도 화면입니다.");
} else if (window.devicePixelRatio == 0.75) {
alert("
저밀도 화면입니다.");
}

CSS를 통해 레이아웃의 크기를 지정할 때에는 가급적이면 절대적인 값(px)보다는 상대적인 값(%)을 사용하는 것이 좋습니다.다음과 같이 장치에 독립적인 메타 데이터를 사용하고 각각의 해상도에 따라 달라져야 하는 크기 문제는 CSS를 밀도 별로 구분하여 적용하는 것이 바람직합니다.

<meta name="viewport" content="target-densitydpi=device-dpi, width=device-width" />
.
:
Posted by .07274.
2012. 11. 23. 17:08

솔라리스 스왑(swap) 사이즈 조정 카테고리 없음2012. 11. 23. 17:08

.. .. ..

1. swap 에 사용될 30G 크기의 파일을 만든다. ( 공간이 넉넉한 경로에 생성 df -h 로 확인)
   /usr/sbin/mkfile 30000m /data2/backup/swapfile

 

2. swap 공간에 추가한다.
   swap -a /data2/backup/swapfile

 

3. swap 파일 확인

   swap -l

 

4. vi /etc/vfstab 에 추가
    ...
    /data2/backup/swapfile - - swap - no

 

5. swap 크기 확인

    swap -s

 

swap 삭제

1. swap 삭제하기
    swap -d /swapfile

 

2. /etc/vfstab 에 추가한 내용 삭제

 

.
:
Posted by .07274.
2012. 11. 22. 12:36

mysql 패스워드 분실시 대처 방법 I.lib()/I.lib(Mysql)2012. 11. 22. 12:36

.. .. ..

출처 : http://www.superuser.co.kr/home/superuserboard/view.html?id=1192&code=mysql&start=640&position=

설치시 에럭 나타날때
[qtam@localhost qtam]$ mysql -u root mysql
ERROR 1045: Access denied for user: 'root@localhost' (Using password: NO)

1. -h (호스트) 적용
2. mysql killall safe_mysqld --user=mysql --skip-grant-table &
3.

MySQL 을 처음 설치한 후 아무런 변경도 하지 않는 경우에는 root 사용자의 암호가 설정되
어 있지 않습니다. 따라서 MySQL 을 처음 설치한 경우에는 다음과 같은 명령으로 MySQL
서버에 연결을 할 수 있습니다.
[wertyu@inos ~]$ mysql -u root mysql

여기서 주의할 점은 mysql 은 -u 옵션으로 사용자 명을 주지 않는 경우 시스템 계정 사용자
의 이름을 이용한다는 것입니다.
[wertyu@inos ~]$ mysql mysql
ERROR 1045: Access denied for user: 'wertyu@localhost' (Using password: NO)

만약 mysql 을 사용하면서 다음과 같은 에러가 발생한다면 사용자에게 암호가 걸려 있는 것
입니다.
[wertyu@inos ~]$ mysql -uroot mysql
ERROR 1045: Access denied for user: 'root@localhost' (Using password: NO)



- mysql root 비밀번호 잊어 먹었을 때
[root@localhost local]# killall mysqld

//권한없이 접속가능하도록하는옵션입니다.
[root@localhost local]# /usr/local/mysql/bin/mysqld_safe --skip-grant-tables &

//mysql로 접속합니다.
[root@localhost local]# mysql
Welcome to the MySQL monitor. Commands end with ; or g.
Your MySQL connection id is 2 to server version: 4.0.20-log

//비밀번호를 변경합니다.
Type 'help;' or 'h' for help. Type 'c' to clear the buffer.
mysql> use mysql
Database changed
mysql> update user set password=password('비밀번호') where user='root';
Query OK, 2 rows affected (0.02 sec)
Rows matched: 2 Changed: 2 Warnings: 0

mysql> exit
Bye

//mysql을 중지시키고 다시 스타트합니다.
[root@localhost local]# killall mysqld
[root@localhost local]# /usr/local/mysql/bin/mysqld_safe &

 

.
:
Posted by .07274.
2012. 11. 22. 11:08

솔라리스 메모리 관리 [펌] I.lib()/I.lib(Unix)2012. 11. 22. 11:08

.. .. ..

[펌] : http://superkkt.com/21?TSSESSION=34642278462d6fb17b9095d9568b2d13

 

솔라리스는 리얼 메모리와 스왑 디바이스를 합친 크기를 메모리로 사용합니다. 예를들어 리얼 메모리가 1기가이고 스왑 디바이스 크기가 1기가라면 전체 메모리는 2기가 입니다.

메모리 할당이 어떻게 이루어지는 보기위해 아래 소스를 컴파일 해서 테스트를 해보겠습니다. 이 코드는 메모리 20메가를 할당 받고아무키나 누르면 할당 받은 메모리를 0으로 초기화 시킵니다. 다시 아무키나 누르면 할당받은 메모리를 반환하고 종료합니다.

# cat test.c
main()
{
char *a;

a = malloc(20485760); // 20메가 할당
getchar(); // 키입력 기다림
memset(a, "0", 20485760); // 할당받은 메모리 0으로 초기화
getchar(); // 키입력 기다림
free(a); // 메모리 반환
}

# gcc -o test test.c


그리고 다른 창을 하나 띄우고 vmstat 1을 실행하세요..

# vmstat 1
kthr memory page disk faults cpu
r b w swap free re mf pi po fr de sr s2 s3 s4 s5 in sy cs us sy id
0 0 0 5846976 1870760 0 0 0 0 0 0 0 0 0 0 0 727 39 65 0 0 100
0 0 0 5846976 1870760 0 65 0 0 0 0 0 0 0 0 0 733 166 103 0 0 100
0 0 0 5846976 1870760 0 0 0 0 0 0 0 0 0 0 0 726 64 78 0 0 100
0 0 0 5846976 1870760 8 80 0 0 0 0 0 0 0 0 0 742 271 145 0 0 100
0 0 0 5846976 1870760 6 70 0 0 0 0 0 0 0 0 0 727 170 104 0 0 100


.
.
.


위에 결과를 보면 free size가 스왑은 5846메가, 리얼 메모리는 1870메가 입니다. 이제 다시 원래 창으로 돌아가서 방금 컴파일한 test 를 실행합니다.

# ./test


다시 vmstat 창을 보면 리얼 메모리에는 변화가 없고 스왑 사이즈만 20메가 줄어들었습니다.

0 0 0 5826864 1870648 0 0 0 0 0 0 0 0 0 0 0 719 39 72 0 0 100
0 0 0 5826864 1870648 0 0 0 0 0 0 0 0 0 0 0 724 41 68 0 0 100
0 0 0 5826864 1870648 0 0 0 0 0 0 0 0 0 0 0 727 49 80 0 0 100
0 0 0 5826864 1870648 0 0 0 0 0 0 0 0 0 0 0 726 39 69 0 0 100
0 0 0 5826864 1870648 0 0 0 0 0 0 0 0 0 0 0 719 39 71 0 0 100


다시 원래 창에서 엔터를 한번 치면..

0 0 0 5826480 1850112 0 1818 0 0 0 0 0 0 0 0 0 731 42 92 2 2 96
0 0 0 5826480 1850112 0 0 0 0 0 0 0 0 0 0 0 727 74 71 0 0 100
0 0 0 5826480 1850112 0 0 0 0 0 0 0 0 0 0 0 725 50 72 0 0 100
0 0 0 5826480 1850112 0 0 0 0 0 0 0 0 0 0 0 721 39 67 0 0 100



리얼 메모리도 20메가 줄어듭니다. 원래 창에서 엔터를 한번 더 쳐서 메모리를 반환하고 프로그램을 종료하면 스왑과 리얼 메모리 사이즈는 원래대로 돌아옵니다.

프로그램이 메모리를 할당 받으면 우선 스왑이 줄어들고 실제로 메모리를 사용할때 리얼 메모리가 줄어드는걸 위에서 확인했습니다.그럼 스왑이 20메가 줄어들때 실제로 스왑 디바이스를 20메가 사용한걸까요? 아닙니다. 실제로 스왑 디바이스를 사용하지않았습니다.

지금 테스트를 하고 있는 시스템은 리얼 메모리 2기가, 스왑 4기가인 시스템 입니다. 합치면 6기가죠.. 위에 vmstat의swap 부분의 수치를 보세요.. free가 5826메가로 나오죠.. 이건 swap이 스왑 디바이스만을 나타내는게 아니라 리얼메모리와 스왑을 합친 크기를 나타내는걸 보여줍니다.


그럼 이제 프로그램이 메모리를 20메가 할당할때 실제로 스왑 디바이스가 사용되지 않았다는걸 확인해 보겠습니다.

test 프로그램을 실행시키기 전에 swap -l을 실행해 보세요..

# swap -l
swapfile dev swaplo blocks free
/dev/dsk/c0t0d0s1 118,25 16 8392048 8392048

결과를 보면 스왑 디바이스의 크기가 8392048 블럭(1블럭=512byte)인데 free도 같은 값을 가지는걸 보면 하나도사용을 안한걸 알 수 있습니다. 이제 다른 창에서 test 프로그램을 실행시키고 다시 swap -l을 해보세요..

# swap -l
swapfile dev swaplo blocks free
/dev/dsk/c0t0d0s1 118,25 16 8392048 8392048

보시다시피 아무 변화가 없습니다. 분명히 테스트 프로그램은 메모리 20메가를 할당 받았고 vmstat에서는 swap이 20메가 줄었는데.. 실제 스왑 디바이스의 크기에는 변화가 없습니다.

그럼 언제 스왑 디바이스를 쓸까요? 잘 아시겠지만 리얼 메모리가 모두 소진되기 직전에 사용이 됩니다. 이 시스템은 리얼 메모리가2기가니까 2기가만큼 메모리를 사용하면 그 다음부터 할당되는 메모리는 스왑 디바이스를 사용하겠죠.. 이걸 확인하기 위해서/tmp 디렉토리를 사용하겠습니다.

솔라리스에서 /tmp = 메모리 입니다. /tmp에 파일을 만들면 메모리에 파일을 만드는 겁니다. 그래서 df -k에서 /tmp의 available size가 vmstat의 swap과 거의 같은 값을 가집니다.

# pwd
/tmp

# df -k /tmp
Filesystem kbytes used avail capacity Mounted on
swap 5825016 0 5825016 0% /tmp

# vmstat 1
0 0 0 5818536 1888328 0 9 0 0 0 0 0 0 0 0 0 732 61 73 0 0 100
0 0 0 5818536 1888328 0 0 0 0 0 0 0 0 0 0 0 725 41 73 0 0 100


# mkfile 1g test.zip

# df -k /tmp
Filesystem kbytes used avail capacity Mounted on
swap 5817752 1048576 4769176 19% /tmp

# vmstat 1
0 0 0 4771072 840880 0 9 0 0 0 0 0 0 0 0 0 727 51 72 0 0 100
0 0 0 4771072 840880 0 0 0 0 0 0 0 0 0 0 0 726 50 77 0 0 100


/tmp에 test.zip이라는 1기가 사이즈의 파일을 만드니 메모리가 1기가 사용되었죠.. 그럼 스왑 디바이스의 상태를 보겠습니다.

# swap -l
swapfile dev swaplo blocks free
/dev/dsk/c0t0d0s1 118,25 16 8392048 8392048

아직 변화가 없습니다. 메모리 1기가를 사용해도 리얼 메모리의 여유가 840메가 정도 있기 때문이죠.. 그럼 1.5기가의 파일을더 만들어 보겠습니다. 예상대로라면 840메가의 리얼 메모리를 사용하고 모자라는 부분은 스왑 디바이스를 사용하겠죠..

# mkfile 1500m test2.zip

이제 시스템이 무지하게 느려집니다.. 왜냐면 리얼 메모리가 모두 소진되었으니 리얼 메모리 확보를 위해 사용하지 않는 부분은 모두스왑 디바이스로 페이지 아웃 시켜버리기 위해서죠.. 엄창난 페이징이 발생하기 때문에 거의 다운 상태에 가깝게 느려집니다.

그리고 다시 살아났을때 vmstat의 결과 입니다.

# vmstat 1
kthr memory page disk faults cpu
r b w swap free re mf pi po fr de sr s2 s3 s4 s5 in sy cs us sy id
0 0 34 3242368 1904616 7 11 0 0 0 0 0 0 0 0 0 721 60 83 0 0 100
0 0 34 3242368 1904616 0 0 0 0 0 0 0 0 0 0 0 722 41 69 0 0 100
0 0 34 3242368 1904616 0 0 0 0 0 0 0 0 0 0 0 727 49 75 0 0 100


swap은 정확하게 1.5기가 줄었는데 오히려 리얼 메모리는 많이 올라갔습니다. 이게 페이징의 결과 입니다. 메모리에서 사용되지않는 부분은 모두 스왑 디바이스로 보내버리고 리얼 메모리를 확보를 한거죠.. 이제 스왑 디바이스의 상태를 보겠습니다.

# swap -l
swapfile dev swaplo blocks free
/dev/dsk/c0t0d0s1 118,25 16 8392048 3173840

환산해보면 2.6기가 정도 스왑 디바이스를 사용 했습니다. 실제로는 test2.zip을 만들면서 700메가의 스왑만 필요했지만 메모리 페이징을 했기 때문에 많은 스왑 공간을 사용한겁니다.


icon_gima25.gif 엄청 기네요.. 두서 없이 적었는데.. 결론은..

프로그램이 메모리를 사용하면 swap을 사용한걸로 나오는데 이 swap이 실제 스왑 디바이스를 의미하는게 아니라 리얼 메모리 +스왑 디바이스를 의미하는 겁니다. 그래서 swap이 사용되었다고 해서 무조건 스왑 디바이스가 사용된거라고 볼 수는 없는겁니다.리얼 메모리가 모두 소진되었을때만 실제 스왑 디바이스가 사용되는 겁니다.


리눅스와의 차이점은 리눅스는 리얼 메모리와 스왑은 완전 별개의 것으로 보인다. 그러나 솔라리스는 이 두개를 하나의 개념으로 보여준다.

 

.
:
Posted by .07274.
2012. 11. 21. 16:59

오라클 커넥션 정보 I.lib()/I.lib(Oracle)2012. 11. 21. 16:59

.. .. ..

[펌] : http://tiamo.tistory.com/3

 

SELECT count(*)
FROM v$session s
WHERE s.username IS NOT NULL
AND NVL (s.osuser, 'x') <> 'SYSTEM'
AND s.TYPE <> 'BACKGROUND';



SELECT /*+ rule */
s.status "Status", s.serial# "Serial#", s.TYPE "Type",
s.username "DB User", s.osuser "Client User", s.server "Server",
s.machine "Machine", s.module "Module", s.terminal "Terminal",
s.program "Program", p.program "O.S. Program",
s.logon_time "Connect Time", lockwait "Lock Wait",
si.physical_reads "Physical Reads", si.block_gets "Block Gets",
si.consistent_gets "Consistent Gets",
si.block_changes "Block Changes",
si.consistent_changes "Consistent Changes", s.process "Process",
p.spid, p.pid, s.serial#, si.sid, s.sql_address "Address",
s.sql_hash_value "Sql Hash", s.action
FROM v$session s, v$process p, sys.v_$sess_io si
WHERE s.paddr = p.addr(+)
AND si.sid(+) = s.sid
AND s.username IS NOT NULL
AND NVL (s.osuser, 'x') <> 'SYSTEM'
AND s.TYPE <> 'BACKGROUND'
ORDER BY 3

.
:
Posted by .07274.