안드로이드 폰을 sshd 서버로 사용
VLC player 를 이용해서 sshd 서버의 파일을 play 하면 renderer 를 chromecast 로 할 수 있다.sshd server 로 열어놓으면, 폰이 여러개인 경우 유용할 듯 하다.
sshd
- SimpleSSHD : android 용 sshd 서버 설정
그래서 모든 개발은 feature 를 따서 진행하고, 개발이 완료되면 master 로 merge request 를 보내서 merge 를 한다. 그러고 나서 master 에서 많은 test 가 진행이 되고나서, stable 한 버전을 하나 만들 때 production branch 로 merge 를 해서 tag 를 붙이면 된다. 그래서 이 production branch 는 계속 유지가 된다.
여기 를 보면, production branch 를 2개를 둘 수도 있다. pre-production, production 그래서 pre-production 에서 흔히 test server 에 deploy 를 하고, 이후에 여기서 다시 실제 staging version 으로 production branch 를 뽑는 방식으로 사용하는 듯 하다.
Release branches with GitLab flow 에는 release branch 에 대한 사용법도 나온다. 이것은 거의 git flow 의 release branch 처럼 사용하는 방식인 듯 보인다. 이 경우 production branch 를 따로 두는 것은 아닌 듯 하다.
git flow init 시에 설정을 아래처럼 잡아준다.
C:\>git flow init -f Which branch should be used for bringing forth production releases? - master - prod Branch name for production releases: [prod] Which branch should be used for integration of the "next release"? - master Branch name for "next release" development: [pre-prod] master How to name your supporting branch prefixes? Feature branches? [feature/] Bugfix branches? [bugfix/] Release branches? [release/] Hotfix branches? [hotfix/] Support branches? [support/] Version tag prefix? [] Hooks and filters directory? [C:/a/prog/nodejs/jprice/.git/hooks]
자바 / 가비지 컬렉터 /
G1은 CMS (Concurrent Mark-Sweep Collector)의 장기 교체 계획이다.
G1과 CMS를 비교해서, G1의 더 나은 점은
오래된 garbage collectors (직렬, 병렬, CMS)는 모두 heap을 fixed memory size의
의 세 섹션으로 구성한다.
모든 메모리 객체는 이 세 섹션 중 하나에 들어간다.
G1 collector는 다른 접근 방식을 취한다.
heap은 equal-sized heap regions 의 집합으로 나뉜다. 각각의 region은 virtual memroy 의 연속된 범위이다.
heap ---> heap region
|
+---> heap region
|
+---> heap region
특정 region 집합에는 이전 collector와 동일한 역할 (eden, survivor, old)이 할당되지만 정의된 fixed size 는 없다. 이것이 메모리 사용에 있어서 더 큰 유연성을 제공한다.

garbage collections 을 수행 할 때 G1은 CMS collector(Concurrent Mark-Sweep Collector)와 유사한 방식으로 작동한다.
G1은 동시 전역 마킹 단계(concurrent global marking phase)를 수행하여 heap 전체에서 객체의 liveness 를 결정한다.
마크 단계가 완료되면 G1은 어느 region이 많이 비어 있는지 알게 된다. 이 region에서 먼저 collect하여 일반적으로 많은 양의 여유 공간을 생성한다. 이러한 garbage collection 방법이 Garbage-First 라고 불리는 이유이다.
이름에서 알 수 있듯이 G1은 회수 가능한(reclaimable) object들, 즉 garbage로 가득 찬 heap region에 수집 및 압축 활동(collection and compaction activity)을 집중시킨다.
G1은 pause prediction model(정지 예측 모델)을 사용하여 user-defined pause time target(유저가 정의한 정지 시간 목표)를 충족시키고 지정된 pause time target를 기반해서 "수집 할 영역(region)의 수"를 선택합니다.
G1 이 reclamation 을 할 만큼 오래(ripe)됐다고 판단한 region은 evacuation(방출) 을 사용하여 garbage collect 가 된다.
G1은 "힙의 하나 이상의 region"에서 "힙의 단일 region"으로 객체를 복사하고 프로세스에서 둘 영역 모두의 메모리를 압축하고 해제한다. --> 여러개로 흩어진 region 을 하나의 연속된 공간으로 모으고, 이것을 하나의 region 으로 처리한다?
이러한 evacuation은 multi processors 에서 병렬로 수행되어 pause times을 줄이고 처리량을 증가시킨다.
따라서 G1은 각각의 garbage collection에서 지속적으로 동작하여 단편화를 줄이고 user-defined pause times 내에서 작업한다.
이것은 이전의 두 가지 방법으로는 불가능하다. CMS (Concurrent Mark Sweep) garbage collector 는 압축(compact)을 수행하지 않는다. ParallelOld garbage collection은 전체 힙 압축(whole-heap compaction) 만 수행하므로 상당한 pause times이 발생한다.
G1은 real-time collector가 아니다. 즉, real-time os 처럼 time critical 하지 않다. 높은 확률로 pause time target를 충족하지만, 절대적으로 확신할 수 있는 것은 아니다.
이전 collection 의 데이터를 기반으로 G1은 사용자가 지정한 target time 내에 collect 할 수있는 "region의 수"를 추정한다.
따라서 collector 는 region을 수집하는 비용에 대해 reasonably accurate model(합리적으로 정확한 모델)을 갖고있고, 이 모델을 사용하여 pause time target 내에 어느 region 을 collect 할지 얼마나 많은 region 을 collect 할 지를 결정한다.
참고 : G1에는 concurrent (애플리케이션 스레드와 함께 실행 (예 : refinement, marking, cleanup))와 parallel (멀티 스레드, 예를 들어 stop-the-world) 단계가 있다. full garbage collection은 여전히 단일 스레드이지만, 잘 tuning 하면 애플리케이션이 full GC를 피할 수 있다.
ParallelOldGC 또는 CMS collector에서 G1으로 마이그레이션하면 JVM 프로세스 크기가 더 커질 수 있다. 이것은 Remembered Sets 및 Collection Sets과 같은 "accounting" data structures 때문이다.
G1의 첫 번째 초점은 limited GC latency time 의 큰 heap이 필요한 애플리케이션을 실행하는 사용자에게 솔루션을 제공하는 것이다.
약 6GB 이상의 힙 크기와 0.5 초 미만의 안정적이고 예측 가능한 pause time 을 의미한다.
CMS 또는 ParallelOldGC garbage collector로 실행중인 응용 프로그램 중 G1로 전환하는 것이 좋은 경우(다음중 하나에 해당하면 G1 을 사용하는 것이 좋다.)
참고 :
- CMS 또는 ParallelOldGC를 사용하고 있고 응용 프로그램에 garbage collection pauses가 길지 않으면 현재 collector를 유지하는 것이 좋다.
- 최신 JDK를 사용해도 G1 collector 를 꼭 사용하지 않아도 된다.
trx.table('...') 을 사용하자.trait('DatabaseTransactions'); 을 사용할 때는 Lucid 를 사용하지 말자. 이유는 분석을 하지 않아서 잘 모르겠지만, Lucid ORM 을 사용하면, transaction 으로 insert 한 record 를 확인할 수 없었다.const { test, trait, before, after } = use('Test/Suite')('Solicitor'); const sinon = require('sinon'); const Product = use('App/Models/Product/Product'); const Database = use('Database'); trait('DatabaseTransactions'); test('test-db-insert', async ({ assert }) => { const trx = await Database.beginTransaction(); const productId = 130; // canceled // const productId = 302; // not active yet const product = await Product.find(productId, trx); const mclass = new MyClass(prodcutId); await mclass.run(); // await Product.find(productId, trx) --> 제대로 동작하지 않는다. const product2 = await trx.table('product').where('id', productId).first(); assert.equal(product.name, product2.name); trx.rollback(); });
node test_ace.js test -f myclass.spec.js
timeout(0)Error: Test timeout, ensure "done()" is called; ...
test('test-db-insert', async ({ assert }) => { const trx = await Database.beginTransaction(); ... assert.equal(product.name, product2.name); trx.rollback(); }).timeout(0);
trx.rollback()Database.beginTransaction(); 을 사용하면, 자동으로 trx.rollback() 을 해주기는 하지만, 만약 여러 test 내에서 각각 trx 를 호출하는 경우라면, 각 test 마다 trx.rollback() 을 해줘야 한다. Error: Test timeout, ensure "done()" is called; ...